Why does the generated form's validation check the changeset's `:action` field instead of `:valid?`? - phoenix-framework

For example, issuing the
mix phx.gen.html Accounts User users name:string age:integer
command from the docs would generate form.html.eex:
<%%= form_for #changeset, #action, fn f -> %>
<%%= if #changeset.action do %>
<div class="alert alert-danger">
<p>Oops, something went wrong! Please check the errors below.</p>
</div>
<%% end %>
<%= for {label, input, error} <- inputs, input do %>
<%= label %>
<%= input %>
<%= error %>
<% end %>
<div>
<%%= submit "Save" %>
</div>
<%% end %>
Is there a reason for not checking #changeset.valid? == false instead?
The current form is indeed shorter, and it has been educational to learn that the :action key is nil only, when there has been no errors.
Is there any other consideration that one would need to take into account (e.g., adding more fields later), or this is just a matter of personal preference?

Somehow missed the Phoenix.HTML.Form documentation, where in the "A note on :errors" section it says that
If no action has been applied to the changeset or action was set to
:ignore, no errors are shown on the form object even if the changeset
has a non-empty :errors value.
This is useful for things like validation hints on form fields, e.g.
an empty changeset for a new form. That changeset isn’t valid, but we
don’t want to show errors until an actual user action has been
performed.
An empty changeset is indeed invalid by default:
iex> %Ecto.Changeset{}
#Ecto.Changeset<action: nil, changes: %{}, errors: [], data: nil, valid?: false>

Related

ckeditor doesnt show anything in the edit form and the dbms doesnt even load in the editor

I tried the ckeditor and it works fine when adding or making a new post but the problem is when I try and edit the post.
it doesn't load properly and it doesnt show anything like the code , or even a spec, it just shows the pre default ckeditor list and it doesn't even show any data coming from the database.
any help would really be great, and info would be awesome.
I have made it into a form and then rendering it so that I can just call the function like so.
This is the _form
<p>
<%= f.label :text %><br>
<%= f.cktext_area :text, :value => 'Default value', :id => 'sometext' %>
</p>
Now this is in my edit
<%= render 'form' %>
I tried adding the raw into it like so
<%= raw render 'form' %>
or even into the _form but it doesn't seem to show properly
after tinkering and trying the usual thing the codes show it.
<p>
<%= f.label :text %><br>
<%= f.text_field :text %>
</p>
when I try it and add this now it shows here , but the ckeditor doesn't show properly.
Just give this:
<p>
<%= f.label :text %><br>
<%= f.cktext_area :text %>
</p>
I hope you are calling this partial inside a form_for.
Update the answer,
Just remove
:value => 'Default value',

Else part is not working in Rails ajax form

I have a Rails ajax form to submit.When user will give the correct data it will search the database and do the operation accordingly.If user is giving the Wrong data it should display user to alert message.But it is not happening like that.
I am explaining my codes below.
home.html.erb
<% if current_admin %>
<p class="flash-message"><%=flash[:notice]%></p>
<div class="col-md-6" style="float:none; margin:auto;">
<%= form_for :sdf ,:url => {:action => "scan_report" },remote: true do |f| %>
<% if params[:receipt_no] %>
<div class="input-group bmargindiv1 col-md-12"> <span class="input-group-addon text-left">Receipt No. Scan :</span>
<%= f.text_field :Receipt_No,:class => "form-control", :value => params[:receipt_no] %><%= f.submit "Scan Report" %>
</div>
<% else %>
<div class="input-group bmargindiv1 col-md-12"> <span class="input-group-addon text-left">Receipt No. Scan :</span>
<%= f.text_field :Receipt_No,:class => "form-control",placeholder:"Receipt No. scan" %><%= f.submit "Scan Report" %>
</div>
<% end %>
<% end %>
<% end %>
controller/homes_contorller.rb
class HomesController < ApplicationController
def home
#sdf=TSdf.new
respond_to do |format|
format.html
format.js
end
end
def scan_report
if #sdf=TSdf.find_by_Receipt_No(params[:sdf][:Receipt_No])
if #sdf && #sdf.HCSY_Status=='YES'
#hcsy=THcsy.find_by_Sdp_Id(#sdf.Sdp_Id)
#hcsy_deatils=THcsyDetails.find_by_HCSY_ID(#hcsy.id)
#woods=THcsyFundTypeMaster.find_by_Fund_Type_Code(1)
#burn=THcsyFundTypeMaster.find_by_Fund_Type_Code(2)
#good=THcsyFundTypeMaster.find_by_Fund_Type_Code(3)
#swd=THcsyFundTypeMaster.find_by_Fund_Type_Code(5)
#photo=THcsyFundTypeMaster.find_by_Fund_Type_Code(6)
end
else
flash[:notice]="Not Found"
end
end
end
In this form its only taking the correct input but if user is trying to give the wrong input the else part is not executing.Please help me to resolve this error and let me to know how can i make this ajax call in below format.
$('form').submit(function() {
var valuesToSubmit = $(this).serialize();
$.ajax({
type: "POST",
url: $(this).attr('action'), //sumbits it to the given url of the form
data: valuesToSubmit,
dataType: "JSON" // you want a difference between normal and ajax-calls, and json is standard
}).success(function(json){
console.log("success", json);
});
return false; // prevents normal behaviour
});
Please help me.I am using Rails version 3.2.19.
Here you send AJAX POST request to scan_report, and if it is successful it should render template scan_report.js.erb, and rendered template will appear in json variable in success callback.
But if params are not valid, the same template is rendered, but all instance variables are missing. And probably empty json is returned or an error appears in log.
Anyway, if you'd like to change flash in remote form, you should put custom code in fail callback. Something like
$("#flash").html('<%= j render flash[:notice] %>');

How to Accept ONLY Two Keys Before User :Submit?

I want people to be able to challenge their habits. If they miss a day they may put "/" if they miss two days in a row they must put "X". Three X's means they failed the challenge.
How can I force the User to only be able to submit X's and /'s as valid keys in the :missed input field?
_form excerpt
<%= simple_form_for(#habit) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :missed %>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
Github: https://github.com/RallyWithGalli/ruletoday
Thanks in advance for your help. You rock!
You can use a select tag to limit users' options like this
<%= select_tag(:missed , options_for_select([['/', '/'], ['X', 'X']])) %>

DocPad: Empty or Missing YAML Elements

I have the following in one of my Layout files...
<% for link in #document.nextlink[0..0]: %>
<% if (link.name): %>
<ul class="actions">
<li><%- "#{link.helptext}" %></li>
</ul>
<% end %>
<% end %>
This works great. Unless, nextlink is not in my YAML at all. But that's what I want. Sometimes I want to have that button called Next and sometimes I do not.
if nextlink is not in my YAML, the DocPad compiler throws an error.
Any help would be much appreciated.

RoR: How can I get my microposts to show up?

Here is the users show view where they are supposed to show up. ..
<section>
<div id= "purchases">
<%= render 'shared/micropost_form_purchase' %>
</div>
<div id="sales">
<%= render 'shared/micropost_form_sale' %>
</div>
</section>
<%= #sales %> <%# This is just to see if it outputs anything. It doesn't :( %>
<div id="purchases list">
<ol class="microposts">
<%= render #purchases unless #purchases.nil? %>
</ol>
</div>
<div id="sales list">
<ol class="microposts">
<%= render #sales unless #sales.nil? %>
</ol>
</div>
so the forms (partials) are loading fine, but then when I make a post, in either one, neither the purchases list nor the sales list shows up. I checked the database and they are being created along with an entry in the column indicating kind (either sale or purchase).
Here are the forms:
<%= form_for (#micropost) do |f| %>
<div class="field no-indent">
<%= f.text_area :content, placeholder: "What's something else you want to buy?" %>
<%= hidden_field_tag 'micropost[kind]', "purchase" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
and
<%= form_for (#micropost) do |f| %>
<div class="field no-indent">
<%= f.text_area :content, placeholder: "What's something else you want to buy?" %>
<%= hidden_field_tag 'micropost[kind]', "sale" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
also, here is the show part of the users_controller.rb
def show
#user = User.find(params[:id])
#micropost=Micropost.new
#microposts = #user.microposts.paginate(page: params[:page])
end
and here is the show part of the microposts_controller.rb
def show
#micropost = Micropost.find(params[:id])
#microposts = Micropost.where(:user_id => #user.id)
#purchases= #microposts.collect{ |m| m if m.kind == "purchase"}.compact
#sales = #microposts.collect{ |m| m if m.kind == "sale"}.compact
end
additionally, with the help of this post (http://stackoverflow.com/questions/12505845/ruby-error-wrong-number-of-arguments-0-for-1#12505865) the variables #microposts, #purchases, and #sales are all outputting correctly in the console.
can anyone help me out?
edit: using scopes as suggested by the answer given works in the console (it outputs everything correctly, but they still don't show up in the view. Does this mean it is something wrong with my syntax for the users show page?
edit 2:
Here is the view/microposts/_micropost.html.erb code
<li>
<span class="content"><%= micropost.content %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(micropost.created_at) %> ago.
</span>
<% if current_user?(micropost.user) %>
<%= link_to "delete", micropost, method: :delete,
confirm: "You sure?",
title: micropost.content %>
<% end %>
</li>
I'm making some assumptions without seeing more of your code, but it looks like you could
write what you've shown a little differently. I'm assuming your databases are migrating
and have the required columns, e.g., Micropost#kind, Micropost#user_id, etc.
You can use scopes to refine a collection of microposts more expressively. It might be helpful to read
up about ActiveRecord scopes: http://guides.rubyonrails.org/active_record_querying.html#scopes.
class Micropost < ActiveRecord::Base
belongs_to :user
scope :purchases, where(:kind => "purchase")
scope :sales, where(:kind => "sale")
# your code
end
I'm also assuming your user has many microposts:
class User < ActiveRecord::Base
has_many :microposts
# your code
end
For your forms, I'd suggest attaching your hidden field to the form object (f.hidden_field) so
you don't have to specify the name as 'micropost[kind]'.
<%= form_for(#micropost) do |f| %>
<div class="field no-indent">
<%= f.text_area :content, placeholder: "What's something else you want to buy?" %>
<%= f.hidden_field :kind, :value => "sale" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
In MicropostsController#show, you can use your new scopes:
def show
#micropost = Micropost.find(params[:id])
#microposts = #user.microposts
#purchases = #microposts.purchases
#sales = #microposts.sales
end
You should also confirm that your MicropostsController#create action is actually adding
the microposts to the user sending the form (I'm assuming a current user method).
def create
#micropost = current_user.microposts.create(params[:micropost])
# yada
end
You can also confirm expected results on rails console after creating purchases or sales micropost with:
Micropost.purchases
Micropost.sales
Again, I could be missing something without seeing more of the code base.
Check Micropost.count, #purchases.count, #sales.count (by printing them in the controller, or some part of the view) to see if the records actually exist.
Also, if you want to render collections likes #sales and #purchases, you need to make sure that the model partial exists (_micropost.html.erb in your case). That is probably where you need to look for the view errors. For all you know, that file could be empty, thus no errors will show up at all.
The problem might also lie in your microposts#create (or whichever action that you are saving the micropost in), the micropost should be associated with the current_user:
#micropost = current_user.microposts.build(params[:micropost])
Taking this and your previous question into account, I suggest you go through the original code for the RoR tutorial again (and verify that all tests are passing) before taking it apart. You can always add new tests to it for your experiments and they will help in figuring out where you went wrong.

Resources