Problem accessing variable in a nested form partial - ruby-on-rails

I have a nested form in a rails view that is called like this
<% f.fields_for :invoice_item_numbers do |item_no_form| %>
<%= render 'invoice_item_number', :f => item_no_form %>
<% end %>
and the partial (_invoice_item_number.html.erb) looks like this
<div class='invoice_item_numbers'>
<% if f.object.new_record? %>
<li><%= f.label :item_number %><%= f.text_field :item_number %>
<%= link_to_function "remove", "$(this).parent().remove()", :class => 'remove_link' %></li>
<% else %>
<li class="inline"><%= f.label :item_number %><%= f.text_field :item_number %>
</li><li class="inline"><%= f.label :description %><%= invoice_item_number.description %></li><li><%= f.label :amount %><%= f.text_field :amount %>
<%= f.check_box '_destroy', :class => 'remove_checkbox' %>
<%= f.label '_destroy', 'remove', :class => 'remove_label' %></li>
<% end %>
</div>
This fails with the error message
undefined method `description' for nil:NilClass
Why does invoice_item_number return a nil object in this partial? It is obviously being defined somehow because if I change it to something else (e.g. item_number.description then the error message becomes undefined local variable or methoditem_number' for #instead. The invoice_item_number object that is being displayed by this partial is being used perfectly well by the form helpers as<%= f.text_field :item_number %>and<% f.text_field :amount %>both work perfectly well. I have tried a number of solutions such as using#invoice_item_number` and explicitly defining an object in the render method but these have not worked.
Presumably there is a very simple answer to this.

Just re-read the Ryan's scraps post on nested forms at http://ryandaigle.com/articles/2009/2/1/what-s-new-in-edge-rails-nested-attributes and found the answer. It was sort of in my code already but I didn't understand what was happening. I can access the invoice_item_number object with f.object so replacing <%= invoice_item_number.description %> with <%= f.object.description %> solved my problem.

how about changing:
<%= invoice_item_number.description %>
to
<%= f.label :description %>
or if you need a field:
<%= f.text_field :description %>

Related

Passing information to a controller through params (not saving it to the db). How to put it inside a hash like the users params hash

I have information that is passed to a controller method but isn't saved to the DB. I want to access this information, that is passed to the controller method as a whole hash, but it is all individual data as you will see below.
Here is the params:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"0O7pbNNrddHCyPL9B/avUUD85574rFBfS57h+aWKK/mBakPSn5iHJKHhPmvuJVfyWxjBsAQn2kagwkTOALEKRg==", "page"=>{"content_top"=>"", "content_bottom"=>""}, "header1"=>"iijijij", "column1"=>"ijijijij", "header2"=>"", "column2"=>"", "header3"=>"", "column3"=>"", "header4"=>"", "column4"=>"", "commit"=>"Save", "guide_id"=>"dungeon-boss", "category_id"=>"heroes", "id"=>"link-skill"}
As you can see there is a page hash and after, it is header1 column1 header2 column2... and so on. With the header1 info, I'm trying to put it inside a params hash like the page hash has for the values passed in it. So it's like "table" =>{"header1"=>"iijijij", "column1"=>"ijijijij", "header2"=>"", "column2"=>"", "header3"=>"", "column3"=>"", "header4"=>"", "column4"=>""}
I'm sure there is something I need to add to the form so it know to group them like this. Here is the form I currently have
<% if (current_user.mod_of_game?(#guide) unless current_user.nil?) %>
<%= form_for([#category, #page], url: update_pages_path) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :content_top, "Top Content" %>
<%= f.text_area :content_top, :class => 'editor' %>
<%= f.label :content_bottom, "Bottom Content" %>
<%= f.text_area :content_bottom, :class => 'editor' %>
<!-- to be in one hash when passed -->
<%= text_field_tag :header1 %>
<%= text_field_tag :column1 %>
<%= text_field_tag :header2 %>
<%= text_field_tag :column2 %>
<%= text_field_tag :header3 %>
<%= text_field_tag :column3 %>
<%= text_field_tag :header4 %>
<%= text_field_tag :column4 %>
<!-- end -->
<%= f.submit "Save" %>
<% end %>
I cant find what I need to add to make the text_field_tag data all be in one hash when passed.(the text_field_tag is purposely not being saved to the DB on form submit, it just needs to be passed to the method and grouped inside a hash)
how about using fields_for like this
<%= form_for([#category, #page], url: update_pages_path) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :content_top, "Top Content" %>
<%= f.text_area :content_top, :class => 'editor' %>
<%= f.label :content_bottom, "Bottom Content" %>
<%= f.text_area :content_bottom, :class => 'editor' %>
<!-- to be in one hash when passed -->
<%= f.fields_for :table do |t| %>
<%= t.text_field_tag :header1 %>
<%= t.text_field_tag :column1 %>
<%= t.text_field_tag :header2 %>
<%= t.text_field_tag :column2 %>
<%= t.text_field_tag :header3 %>
<%= t.text_field_tag :column3 %>
<%= t.text_field_tag :header4 %>
<%= t.text_field_tag :column4 %>
<% end %>
<!-- end -->
<%= f.submit "Save" %>
<% end %>
You can simply use the array way if you want to send the data that doesn't belong to the model, in params hash inside page key. Here's how:
<%= text_field_tag 'page[header1]' %>
Not only this, if you would like to use another key, you can use that as well like <%= text_field_tag 'custom_key[header1]' %>

How to add custom validation error message adjacent to input fields in Rails 3?

My Code in View Page(views/session/new.html.erb) :
< %= form_for(:session, :url => sessions_path) do |f| %>
<%= f.label :email, 'Username'%>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit 'Login'%>
<%= link_to 'Forgot Your Password?', new_password_reset_path >
< % end %>
I have written proper validation codes in my model file.
But I want that on Submit, the validation errors should pop up at the adjacent to the fields rather than at the top of the Page.
Thanks in Advance !
If you're inclined to use Rails' built-in server side validations, you can check for whether validation errors exist, then print them if they do:
<%= form_for(:session, :url => sessions_path) do |f| %>
<%= f.label :email, 'Username'%>
<%= f.text_field :email %>
<% if f.object.errors[:email] %>
<%= f.object.errors[:email].join(", ") %>
<% end %>
<%= f.label :password %>
<%= f.password_field :password %>
<% if f.object.errors[:password] %>
<%= f.object.errors[:password].join(", ") %>
<% end %>
<%= f.submit 'Login'%>
<%= link_to 'Forgot Your Password?', new_password_reset_path >
<% end %>
Note a few things:
First, because you're passing a symbol, rather than an object in your form, you'll need to access the object's attributes from within the form_for block by invoking f.object.
Second, because some fields may yield more than one validation error, you'll want to print them out in sequence. Using Ruby's join method can help you concatenate these in a coherent manner.
UPDATE:
If you want the errors to render directly beside the corresponding text field, you'll need to apply some CSS. Clearly, it's recommended that a stylesheet be used to for this, but in the interest of simplicity, here's of an example of how this might be rendered using inline styling:
<%= f.text_field :email, :address, :style => "display: inline-block; float: left;" %>
<% if f.object.errors[:email] %>
<span style="display: inline-block; float: left;">
<%= f.object.errors[:email].join(", ") %>
</span>
<% end %>
<div style="clear: left;"></div>
I'd go with something like this:
<%= form_for(:session, :url => sessions_path) do |f| %>
<%= f.label :email, 'Username' %>
<%= f.text_field :email %>
<%= f.object.errors[:email].to_sentence if f.object.errors[:email] %>
<% end %>
I reckon you'll figure out the rest.
You can access the values of error messages of different model attributes with errors hash like errors[:some_attribute_name]. As long as your custom validators store error message in the right model attribute, you can probably do something like this.
< %= form_for(:session, :url => sessions_path) do |f| %>
<%= f.label :email, 'Username'%>
<%= f.text_field :email %>
<%= f.object.errors[:email] %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.object.errors[:password] %>
<%= f.submit 'Login'%>
<%= link_to 'Forgot Your Password?', new_password_reset_path >
< % end %>
I'll let you worry about how the error is displayed beside the form and stuff. :)

Is there a way to use form_for without the enclosing <form> tag?

I want to use
<%= form_for(#modelname) do |f| %>
<%= f.label :foo %>
<%= f.text_field :foo %>
<% end %>
And get only the inner HTML, without the enclosing tag. Is it possible?
I believe that what you are looking for is fields_for.
<%= fields_for #model do |f| %>
<%= f.label :foo %>
<%= f.text_field :foo %>
<% end %>

blank comment entry with rails

I'm trying to add ability to add comments to projects within a "todo" type app and have run into a problem.
I've created a project with comments before and never run into this problem, but basically rails is drawing an empty comment on the project page.
I've tried a few if statements without any luck, does anyone see my problem ?
<% #project.comments.each do |comment| %>
<div class="commentBlock"><strong><%= comment.posted_by %> says:</strong>
<%=raw comment.comment %>
<small><i class="icon-remove"></i> <%= link_to 'Delete', [comment.project, comment],:confirm => 'Are you sure?',:method => :delete %></small></div>
<% end %>
<h3>Leave a comment</h3>
<%= form_for([#project, #project.comments.build]) do |f| %>
<div class="field">
<%= f.hidden_field :posted_by, :value => current_user.username %>
</div>
<div class="field">
<%= f.label :comment %><br />
<%= f.text_area :comment, :class => "tinymce" %><%= tinymce %>
</div>
<p><%= f.submit :class => 'btn' %></p>
<% end %>
Answer was an error in my controller for Projects, referenced #comment like so:
#comment = #project.comments.build(params[:comment]) by accident!!
Changed to:
#comment = #project.comments
And all works as it should :P
thanks for your help, bad "end of the day" error right there :P

RoR field set on form_for

How do you add a field set to a form_for method?
You can use field_set_tag. For example, using a generic 'user' object
For Rails 2.3.x
<% form_for(#user) do |f| %>
<% field_set_tag 'Name' do %>
<%= f.text_field :first_name %>
<%= f.text_field :last_name %>
<% end %>
<% end %>
And for Rails 3.0.0:
<%= form_for(#user) do |f| %>
<%= field_set_tag 'Name' do %>
<%= f.text_field :first_name %>
<%= f.text_field :last_name %>
<% end %>
<% end %>
You need to have a new object or get an existing object from your dc since it is a 'form for' and then you create a form builder f and call methods on that form builder such as the following:
<% form_for(#object) do |f| %>
<%= f.text_field :method_name %>
<% end %>

Resources