I have two models store and category. A store can have many categories and should get stored in categories_stores table. The model relationships are setup properly and I have the following on the store form:
f.input :categories, :as => :check_boxes
And they do indeed display correctly. But creating or editing a store doesn't create / delete those records in the categories_stores table.
Any ideas?
Update: The above code already generates the list correctly (see screenshot and HTML code below) -- the only problem is changes to this aren't getting saved in the DB!
<input id = "merchant_category_ids_" name="merchant[category_ids][]" type="hidden" value="" />
<ol>
<li><input id="merchant_category_ids_1" name="merchant[category_ids][]" type="checkbox" value="6" /> Clothing</li>
<li><input checked="checked" id="merchant_category_ids_2" name="merchant[category_ids][]" type="checkbox" value="5" /> Electronics</li>
</ol>
Sounds like you may be trying to set sub-resources. If that's the case, you can try something like:
<%= f.fields_for :categories do |f_categories| %>
<%= f_categories.input ... %>
<% end %>
Take a look at the fields_for doc for more info.
I know this is already answered, but have you made sure that the following is defined in the respective models?
attr_accessible :categories_stores_attributes
accepts_nested_attributes_for :categories_stores
Related
A parent class 'model'
has_many :modelbodycontacts
has_many :bodycontacts, through: :modelbodycontacts
accepts_nested_attributes_for :modelbodycontacts, allow_destroy: true
modelbodycontacts being a join table for model and bodycontact.
The related controller permits
params.require(:model).permit(:name, :modelbodycontact_attributes)
However, using form_with
<%= form_with(model: model, local: true) do |form| %>
<%= form.fields(:modelbodycontact) do |bodycontact_fields| %>
<% #bodycontacts.each do |bodycontact| %>
<%= bodycontact_fields.check_box :bodycontact_id %><%= bodycontact.name %>
<% end %>
<% end %>
generates the following HTML
<input name="model[modelbodycontact][bodycontact_id]" type="hidden" value="0" /><input type="checkbox" value="1" name="model[modelbodycontact][bodycontact_id]" id="model_modelbodycontact_bodycontact_id" /> Seat
<input name="model[modelbodycontact][bodycontact_id]" type="hidden" value="0" /><input type="checkbox" value="1" name="model[modelbodycontact][bodycontact_id]" id="model_modelbodycontact_bodycontact_id" /> Back
submitting data leads to Unpermitted parameter: :modelbodycontact
There are a few errors here:
the bodycontact_id is not being generated in the HTML code, only the checked/unchecked values, thus a child record cannot be properly created
the parameters are not being permitted; particularly, the reference is to the model name, not its attribute(s)
Documentation indicates that "The form_with method automatically includes the model id as a hidden field in the form." Well, it ain't there... But possibly Rails handles that internally knowing it is a nested
One could revert to form_for and its tried and tested ways, but that will be eventuall be deprecated. How can form_with be properly used here?
changing param option in controller
params.require(:model).permit(:name, modelbodycontact_attributes: [])
and
<%= form.fields("modelbodycontact_attributes[]") do |bodycontact_fields| %>
<% #bodycontacts.each do |bodycontact| %>
<%= bodycontact_fields.check_box :bodycontact_id %><%= bodycontact.name %>
<% end %>
<% end %>
should work i think
I have this line in a form made with Simple Form:
<fieldset>
<legend>Any acessory?</legend>
<li><%= f.input :has_acessory, label: false, collection: ["0","1"], as: :radio_buttons, input_html:{ name: 'has_acessory'} %></li>
</fieldset>
and Simple Form generates this code:
<fieldset>
<legend>Any Acessory?</legend>
<li><div class="input radio_buttons optional lending_has_acessory"><label class="radio"><input checked="checked" class="radio_buttons optional" id="lending_has_acessory_0" name="has_acessory" type="radio" value="0" />0</label><label class="radio"><input class="radio_buttons optional" id="lending_has_acessory_1" name="has_acessory" type="radio" value="1" />1</label></div></li>
</fieldset>
I'm using SQLite3, Where there's a table called lendings with an Integer column called has_acessory and it's default value is: 0
In Lending model:
class Lending < ActiveRecord::Base
attr_accessible :devolution_date, :lending_date, :situation, :description,:has_acessory, :person_id, :equipment_id
#Associations
belongs_to :equipment
belongs_to :person
end
But it doesn't matter which value that I choose in the radio buttons,I always get "0" (the default value)in the has_acessory column.I already checked the params, and I can find "has_acessory" =>"0" or "1".
For me this part is working pretty well, but why can't it be saved in the has_acessory column?
I would try to let rails do more of the work for you.
Please try just <%= f.input :has_acessory %> and see what that gives you.
Having all this <%= f.input :has_acessory, label: false, collection: ["0","1"], as: :radio_buttons, input_html:{ name: 'has_acessory'} %> makes it hard to debug.
Please look at the migration/database and make sure that the field is boolean. If it is, rails will figure out all the right options for you.
Also - you say that the field has a default - but I don't see that in the model. Did you just omit that line in the model? Is it in both the rails model and the database?
Try this
Add this line into the controller method
params[:has_acessory] = params[:has_acessory].to_i
I have an invoice with some lines. A line can only belong to one invoice. This is how my schema looks like:
create_table "invoices" do |t|
end
create_table "lines" do |t|
t.integer "invoice_id"
end
And my models:
class Invoice < ActiveRecord::Base
has_many :lines
end
class Line < ActiveRecord::Base
belongs_to :invoice
end
Now, when creating (or editing) an invoice I would like to show a list with all possible lines (the lines already exist in the database) and have a check box for each line to link it with the invoice.
I had a look at the HABTM problem but I don't think that's what I need here, the problem isn't as complex. I think the problem is me wanting to update the Unit#invoice_id while I am working on the invoice. Can I do this with a nested form or do I need a before_save callback here?
Thanks!
Have a look at Iain's answer. It's definitely the right way to go but... I prefer not to use simple_form or formtastic for this example to keep it as simple as possible.
I used Iain's HTML output to extract the HTML I need. This snippet is the same as Iain's answer without the need of an extra library:
<% Line.all.each do |line| %>
<%= hidden_field_tag "invoice[line_ids][]" %>
<%= check_box_tag "invoice[line_ids][]", line.id, #invoice.lines.include?(line), :id => "invoice_line_ids_#{line.id}" %>
<% end %>
PS: The Line.all and #invoice.lines... should be extracted to the controller and invoice model, they don't belong in the view. They are only used for brevity's sake.
A has_many association also adds the accessor line_ids, which you can create check boxes for.
If you're using simple_form or formtastic it's incredibly easy:
<%= f.input :line_ids, :as => :check_boxes %>
Which will create something like this:
<span>
<input name="invoice[line_ids][]" type="hidden" value="" />
<input checked="checked" class="check_boxes optional" id="invoice_line_ids_1" name="invoice[line_ids][]" type="checkbox" value="1" />
<label class="collection_check_boxes" for="invoice_line_ids_1">Line Name 1</label>
</span>
<span>
<input name="invoice[line_ids][]" type="hidden" value="" />
<input checked="checked" class="check_boxes optional" id="invoice_line_ids_2" name="invoice[line_ids][]" type="checkbox" value="2" />
<label class="collection_check_boxes" for="invoice_line_ids_2">Line Name 2</label>
</span>
And that is all there is to it. No nested forms or anything else needed.
I recommend using the collection_check_boxes helper method:
<%= collection_check_boxes :invoice, :lines, #lines, :id, :name %>
or Haml:
= collection_check_boxes :invoice, :lines, #lines, :id, :name
I'm using fields_for in my form like so
<%= form_for #user %>
...
<%= f.fields_for :photos do |f2| %>
<%= f2.radio_button :public, 'true' %>
<% end %>
...
<% end %>
Here are the radio buttons it generates:
<input id="user_photos_attributes_0_public_true" name="user[photos_attributes][0][public]" type="radio" value="true" />
<input id="user_photos_attributes_0_id" name="user[photos_attributes][0][id]" type="hidden" value="1" />
<input id="user_photos_attributes_1_public_true" name="user[photos_attributes][1][public]" type="radio" value="true" />
<input id="user_photos_attributes_1_id" name="user[photos_attributes][1][id]" type="hidden" value="4" />
<input id="user_photos_attributes_2_public_true" name="user[photos_attributes][2][public]" type="radio" value="true" />
<input id="user_photos_attributes_2_id" name="user[photos_attributes][2][id]" type="hidden" value="5" />
...
I have this in user.rb
has_many :photos
accepts_nested_attributes_for :photos
When form is submitted I get this error:
Error during failsafe response: ActionView::Template::Error
TypeError (expected Hash (got Array) for param `photos_attributes'):
Does anyone know why this is happening?
Btw, I'm using Rails 3.0.0.rc2
How are you saving your model?
If you inspect the params hash, you will get something like:
{ :user => {:photo_attributes => [{:id => 1, :public => true}, {:id => 4, :public => false}] }, :your_other_params => ... }}
So a User.new(params[:user]).save should work. Unless you are passing each hash of attributes instead of the array. See this article if you need a more in-depth detail.
What is in your params hash? That'd help you to trace the problem.
BTW, if you want a "true/false" behavior (I assume that because of the is_public property), rather than "present/non-present", a checkbox should be used. Radio buttons are for mutually exclusive options.
I recently had the same problem. Instead of trying to get the params through the controller, we used the Chrome tools to see what was being passed in the params and found that we were passing an empty hash/array e.g. params[] versus params[:something]
I have a Campaign model which I want the user to be able to check off and on a checkbox for each state, which I want to store in an array in one the fields, like ["CA", "NY", "OH", "FL"].
I'm not sure if serialized is the correct terminology here. I have some form fields generated like so:
<% State::NAMES.each do |state| %>
<%= check_box("states_allowed", state[1], :checked => true) %>
<label for="states_allowed_<%= state[1] %>"><%= state[0] %></label>
<% end %>
In which State::NAMES, is just an array of state names and abbreviations.
So this gives me the HTML of:
...
<input type="hidden" value="0" name="states_allowed[NE]"><input type="checkbox" value="1" name="states_allowed[NE]" id="states_allowed_NE">
<label for="states_allowed_NE">Nebraska</label>
...
But how can I save the check fields? The column content stays null and I don't receive an error.
Something I have tried is putting serialize :states_allowed in my Campaign model, but no luck.
I add the same problem today, it appears the form isn't properly built in the view.
I simply added at the beginning of my create action:
params[:campaign][:states_allowed] = params[:states_allowed]
And it works properly