Rails undefined method form fields_for - ruby-on-rails

I am trying to add dynamic fields to my rails application.
I have a fields_for
<%= form.fields_for :books do |book| %>
<%= render 'book_fields', form: book %>
<% end %>
<%= link_to_add_fields "Add Field", form, :books %>
When it renders book_fields I am getting the following error
If I am passing form in render why would I be getting this error?
I have tried book.label :title but I get the same error but instead of the undefined varaible being form it is book. Any ideas? Thanks in advance.
UPDATE:
<%= form.fields_for :books do |builder| %>
<%= form.label :title %>
<%= form.text_field :title %>
<%= form.hidden_field :_destroy %>
<% end %>
If I remove the partial render and stick the form text fields and labels into the fields_for itself it works. While rendering the partial, that is when I get the error.

Instead using the form block variable as the local in your render method, you have to use the builder one, like:
<%= form.fields_for :books do |book| %>
<%= render 'book_fields', f: book %>
<% end %>
In the partial:
<fieldset>
<%= f.label :title %>
</fieldset>
The error is happening because you're using your "main" form variable, and when the partial is being load, Rails try to find it as a local variable, which doesn't exist in that context.

Related

accessing related record attributes in nested form

In a nested form, that is only used for updates
<%= form_for(#event) do |f| %>
<%= f.fields_for :distances do |distance| %>
<%= distance.check_box :active %>
the form functions in updating the child record. However I cannot call any attirbute of the related record with either for distanceprefix
<%= distance.starting_point %>
How can this value be rendered?
Try like this, it create new object only if not present:
<%= form_for(#event) do |f| %>
<%= f.fields_for :distances, f.object.distances || f.object.build_distances do |distance| %>
<%= distance.check_box :active %>
<%= distance.starting_point %>
<%= distance.object.starting_point %>
renders the child attribute

rails 4.0 beta, fields_for not accepting more than one argument

This works:
<%= f.fields_for :exercise do |builder| %>
<%= render 'exercise_fields', f: builder %>
<% end %>
<%= add_fields "Add Exercise", f, :exercises %>
<%= f.submit %>
but adding another argument (in this case a reference to the object) throws an ArgumentError:
<% #workout.exercises.each do |exercise| %>
<%= f.fields_for :exercise, exercise do |builder| %>
<%= render 'exercise_fields', f: builder %>
<% end %>
<% end %>
<%= add_fields "Add Exercise", f, :exercises %>
<%= f.submit %>
Error: wrong number of arguments (2 for 1)
I've seen this multiple times in different places. Is this a bug or am I making some simple mistake?
Try to pass it as an array:
<%= f.fields_for [:exercise, exercise] do |builder| %>
Woops, it was of course a simple mistake. I was overriding the fields_for helper method in a custom form builder and I only defined it as having one argument.

How to submit multiple, duplicate forms from same page in Rails - preferably with one button

In my new views page I have:
<% 10.times do %>
<%= render 'group_member_form' %>
<% end %>
Now this form contains the fields: first_name, last_name, email_address and mobile_number. Basically I want to be able to fill in the fields of all the forms in one click which then submits each into the database as a unique row/id.
What would be the easiest way to accomplish this?
Note: The number of times do is called from a variable. Any advice welcome, thanks!
You should have only one form (you should put only fields in the group_member_form partial). In your view you should have something like:
<%= form_tag "/members" do %>
<% 10.times do %>
<%= render 'group_member_form' %>
<% end %>
<%= submit_tag "Submit" %>
<% end %>
and in _group_member_form.html.erb you should have
<%= text_field_tag "members[][first_name]" %>
<%= text_field_tag "members[][last_name]" %>
<%= text_field_tag "members[][email_address]" %>
<%= text_field_tag "members[][mobile_number]" %>
This way, when the form submits, params[:members] in the controller will be an array of member hashes. So, for example, to get the email adress from the fourth member after submitting the form, you call params[:members][3][:email_adress].
To understand why I wrote _group_member_form.html.erb like this, take a glance at this:
http://guides.rubyonrails.org/form_helpers.html#understanding-parameter-naming-conventions.
You can also use accepts_nested_attributes_for in your model, and use fields_for on your form.
Submitting multiple forms, afaik, only javascript, if the forms are remote: true, and you run through each of them and then submit.
$("form.class_of_forms").each(function() {
$(this).submit();
});
Alternatively a more up to date approach using form_with and fields_for, without removing the form into a partial, could be written like this:
<%= form_with (url: end_point_path), remote: true do |form| %>
<% (1..5).each do |i| %>
<%= fields_for 'cart_items'+[i].to_s do |fields|%>
<%= fields.text_field :first_name %>
<%= fields.text_field :last_name %>
<%= fields.email_field :email_address %>
<%= fields.number_field :phone_number %>
<% end %>
<% end %>
<%= form.submit "Submit" %>
<% end %>

Rails Nested Attributes Doesn't Insert ID Correctly

I'm attempting to edit a model's nested attributes, much as outline here, replicated here:
<%= form_for #person do |person_form| %>
<%= person_form.text_field :name %>
<% for address in #person.addresses %>
<%= person_form.fields_for address, :index => address do |address_form|%>
<%= address_form.text_field :city %>
<% end %>
<% end %>
<% end %>
In my code, I have the following:
<%= form_for(#meal) do |f| %>
<!-- some other stuff that's irrelevant... -->
<% for subitem in #meal.meal_line_items %>
<!-- # Edit 2: I need to display information here about the subitem
Which I can't find a way to pass it to the partial, or work in
this manner for existing items
-->
<%= subitem.food.name %>
<%= subitem.food.calories %>
<%= f.fields_for subitem, :index => subitem do |line_item_form| %>
<%= line_item_form.label :servings %><br/>
<%= line_item_form.text_field :servings %><br/>
<%= line_item_form.label :food_id %><br/>
<%= line_item_form.text_field :food_id %><br/>
<% end %>
<% end %>
<%= f.submit %>
<% end %>
This works great, except, when I look at the HTML, it's creating the inputs that look like the following, failing to input the correct id and instead placing the memory representation(?) of the model. As a result, an update fails:
<input type="text" value="2" size="30" name="meal[meal_line_item][#<MealLineItem:0x00000005c5d618>][servings]" id="meal_meal_line_item_#<MealLineItem:0x00000005c5d618>_servings">
EDIT:
The reason I'm attempting to do it in this method is that I need to gather some information on associations for existing meal_line_items. For example, in the area where I took out code, I have some code to the effect of:
<%= subitem.food.name %>
<%= subitem.food.calories %>
Getting this information won't work if I am using a form builder with partials, at least, not in my trials.
Edit 2:*
See the edit in the code. Here's my MealLineItem
class MealLineItem < ActiveRecord::Base
# Associations ---------------------
belongs_to :food
belongs_to :meal
end
And meal accepts_nested_attributes for the model. As you can see it belongs to both food and meal model. For the existing meal_line_item I need to do something like:
meal_line_item.food.name
Is there f. missing from <%= fields_for?
--edit
Have you tried:
<%= f.fields_for 'meal[meal_line_item][]', subitem do |line_item_form| %>
--edit
Docs say that it should work without loop too:
<%= form_for(#meal) do |f| %>
<!-- some other stuff that's irrelevant... -->
<%= f.fields_for :meal_line_items do |line_item_form| %>
<%= line_item_form.label :servings %><br/>
<%= line_item_form.text_field :servings %><br/>
<%= line_item_form.label :food_id %><br/>
<%= line_item_form.text_field :food_id %><br/>
<% end %>
<%= f.submit %>
<% end %>
Have to test this but maybe this approach?
_form
<%= form.fields_for :meal_line_items do |meal_line_item_form| %>
<% #meal.meal_line_items.each do |meal_line_item| %>
<%= render :partial => "meal_line_items/meal_line_item", :locals => { :meal_line_item_form => meal_line_item_form, :meal_line_item => meal_line_item } %>
<% end %>
<% end %>
meal_line_items/_meal_line_item.erb
<%= meal_line_item_form.label :servings %><br/>
<%= meal_line_item_form.text_field :servings %><br/>
<%= meal_line_item_form.label :food_id %><br/>
<%= meal_line_item_form.text_field :food_id %><br/>
EDIT
here's a link to an example for setting the formbuilder iterator directly (Rails 2.3.8 though). The associations between Outbreak -> Incidents -> Location should be similiar to the ones for Meal -> Meal_line_items -> Food.
AJAX update of accepts_nested_attributes_for partials
After searching high and low, I found the error. Although I was modifying the partial and was receiving a NameError it's because I was calling the partial from a helper method - exactly the same problem as stated in the following question:
rails fields_for render partial with multiple locals producing undefined variable

How do you pass additional information into a nested form partial?

Based on Railscast 196 and 197, I've created a nested form for adding multiple illustrations (image attachments) to my article model. I have a form like this:
<%= form_for #article, :html => { :multipart => true } do |f| %>
<h2>Illustrations</h2>
<% for illustration in #article.illustrations %>
<%= f.fields_for :illustrations, illustration do |builder| %>
<%= render :partial => "illustration_fields",
:locals => { :f => builder, :illustration => illustration } %>
<% end %>
<% end %>
<p>
<%= f.submit "Submit" %>
</p>
<% end %>
And the _illustration_fields partial looks like this:
<div class="fields">
<p>
<%= f.label :illustration, "Illustration" %><br />
<%= link_to_remove_fields "remove", f %><br />
<%= f.file_field :illustration %>
</p>
</div>
If the illustration already exists, I want to display it on the page inside an image tag. I tried displaying the image inside the partial like this:
<% unless :illustration.illustration.blank? %>
<%= image_tag(:illustration.illustration.url) %>
<% end %>
But it throws up an error:
undefined method `illustration' for :illustration:Symbol
The illustration field definitely exists in the illustration model, as I can display the image inside the main form like this:
<% unless illustration.illustration.blank? %>
<%= image_tag(illustration.illustration.url) %>
<% end %>
It seems that Rails doesn't understand the illustration information into the partial (or I'm not passing it correctly). What is the correct approach to going about this?
Solved it. The illustration object can be accessed from inside the partial as follows. No need to pass it inside the :locals hash.
<% unless f.object.illustration.blank? %>
<%= image_tag(f.object.illustration.url) %>
<% end %>
You got the symbol error because you are accessing the local using : in the unless.
The error
undefined method `illustration' for :illustration:Symbol
means that Ruby looked for a method named illustration on an instance of the Symbol class; the method obviously is not meant to exist in the Symbol class.
The way to access the local variable that is passed in is simply illustration.whatever.whatever (no : is used!).

Resources