ActiveAdmin nested form duplicate - ruby-on-rails

I know there are multiple questions with a similar title to this, but I haven't found anything that resembled my problem. If there is already a solution and thus my question is a duplicate, I'm sorry - I just didn't find it, it's not that I didn't search.
I'm using ActiveAdmin with the ActiveSkin theme. I have a form for my model Agent where I want to use the nested forms for a has_many relation. I created this code in a partial:
<%= semantic_form_for [#agent], builder: ActiveAdmin::FormBuilder do |f| %>
<%= f.semantic_errors %>
<%= f.inputs 'General Information' do %>
<%= f.input :name %>
<%= f.input :description %>
<% end %>
<%= f.inputs 'Capture Columns' do %>
<%= f.has_many :capture_columns, new_record: 'Add Column' do |column| %>
<%= column.input :column_name %>
<%= column.input :column_datatype %>
<% end %>
<% end %>
<%= f.actions do %>
<%= f.action :submit %>
<li class="cancel"><%= link_to 'Cancel', :back %></li>
<% end %>
<% end %>
Basically, this is working, but it looks like this:
Why is the html duplicated (I checked it, it's exactly the same)? What am I doing wrong?
EDIT:
The inner HTML for the nested form is duplicated, too:

Not saying it's the right behavior, but according to the docs, you need to avoid printing to the template when using has_many.
Try using <%- or <% instead of <%= in the f.has_many declaration and block.

There is a loop hear. The problem is simple to solve, just get in the loop and understand why it is looping and how to fix it. You should use binding.pry to test it. You can set a breakpoint in the form with <% binding.pry %> or you can print variables like <% puts column %> in your server log.
<%= f.has_many :capture_columns, new_record: 'Add Column' do |column| %>
<%= column.input :column_name %>
<%= column.input :column_datatype %>
<% end %>

Related

Rails form_for check_box

I'm trying to create a basic survey app. On my take survey page I'm looping through and displaying each answer option as a radio button or checkbox as a form_for to create a user's choice. The choices are working great for the questions that are single choice (or radio buttons), but they aren't saving for multi select questions. I'm pretty sure this has to do with the form I have for the checkbox.
It seems like I should do
<%= f.check_box :answer_id, answer.id %> <%= answer.title %> <br>
similar to how I'm creating the radio button but that throws an error
undefined method `merge' for 14:Fixnum
Here's my code that displays:
<h3>Questions:</h3>
<ul><% #survey.questions.each do |question| %>
<li><p><%= question.title %></p></li>
<% choice = question.choices.build %>
<% if question.single_response == true %>
<%= form_for [question, choice] do |f| %>
<% question.answers.each do |answer| %>
<%= f.radio_button :answer_id, answer.id %> <%= answer.title %><br>
<% end %>
<%= f.hidden_field :survey_id, value: #survey.id %>
<%= f.submit %>
<% end %>
<br />
<% else %>
<%= form_for [question, choice] do |f| %>
<% question.answers.each do |answer| %>
<%= f.check_box :answer_id %> <%= answer.title %> <br>
<%= f.hidden_field :survey_id, value: #survey.id %>
<% end %>
<%= f.submit %>
<% end %>
<br />
<% end %>
<% end %>
</ul>
Any idea what I need to do to get it to save the answer_id to the choice so that it actually creates the choice?
Thanks!
This question is a few years old but I think it deserves a better answer. Since you are using form_for (a model backed form), then you probably want to use the form_for check_box method that you originally tried to use. In your case, it would look like this:
<%= f.check_box :choice, { :multiple => true }, answer.id, false %>
Here is the doc on this.
For checkboxes, you actually want to return an array as the parameter. There is a little funny syntax to this because we don't actually want to use the form builder methods. It should look something like this (adapt to your specific model names and methods)
<%= check_box_tag 'choice[answer_ids][]', answer.id %>
Using this syntax should tell Rails to compile all of the checked checkbox values into an array.
This Railscast goes over the topic.

With simple_form, how to group multiple inputs and still have correct validation error handling

I often have the situation where I need multiple form elements to appear at one place. For instance:
<%= simple_form_for #user do |f| %>
<%= f.input :active_from do %>
<%= f.input_field :active_from %>
to
<%= f.input_field :active_to %>
<% end %>
<% end %>
This is how I do it at the moment. But there are two problems I have with this solution:
For the wrapping input, which field name to pass? In this example, I just took the first
one, but acutally I'd like to pass both (i.e. f.input [:active_from, :active_to] do). However, this is more of a cosmetical thing if problem 2) can be solved otherwise.
Say, both of these fields are required, how to get error messages for both of these? Somehow, the parent element needs to know that at least one of the sub-inputs has an error and there must be some way of displaying messages. Maybe something like that:
<%= simple_form_for #user do |f| %>
<%= f.input :active_from do %>
<%= f.input_field :active_from %>
<%= f.errors_for :active_from %>
to
<%= f.input_field :active_to %>
<%= f.errors_for :active_to %>
<% end %>
<% end %>

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 checkboxes and serialized data

I'm trying to figure out whats the best way to get checkboxes to properly show their current state. This is what I have in my form
<%= form_for #user, :url => user_notification_preferences_path(#user), :method => :put do |f| %>
<%= f.fields_for :notification_preferences, #user.notification_preferences do |p| %>
<%= p.check_box :notify_on_friend_post %>
<%= p.check_box :notify_on_friend_post %>
<%= p.check_box :notify_on_friend_request %>
<%= p.check_box :notify_on_friend_comment %>
<% end %>
<%= f.submit %>
<% end %>
notification_preferences is a serialized hash on my user model
class User < ActiveRecord::Base
serialize :notification_preferences, Hash
My issue that is no matter what I try, I can not get the check boxes to reflect the existing state of the hash values. IE, if the hash already contains :notify_on_friend_post => 1, then the check box for that value should be checked.
The form posts the data fine, and I'm able to update my model as well.
Update
using check_box_tag I can get this to work
<%= p.hidden_field :notify_on_friend_post, :value => "0" %>
<%= check_box_tag "user[notification_preferences][notify_on_friend_post]", "1", #user.notification_preferences[:notify_on_friend_post] == "1" ? true : false %>
ugly but working, still hoping I'm missing something very obvious
I ran into this problem and solved it in a simpler way.
<%= form_for #user do |f| %>
<%= f.fields_for :notifications, #user.notifications do |n| %>
<%= n.check_box :new_task, checked: #user.notifications[:new_task] == "1" %>
<% end %>
<%= f.submit %>
<% end %>
In this way you let the magic of check_box to the work and don't need to have a hidden_field because Rails will provide one for you. Still unsure why you need a "checked" field, but it seemed to not work without one.
Try something like this:
<%= form_for #user, :url => user_notification_preferences_path(#user), :method => :put do |f| %>
<%= check_box_tag "user[notification_preferences][]", :notify_on_friend_post, #user.notification_preferences.try(notify_on_friend_post) %>
<%= f.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

Resources