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]
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 am working on inviting new users. In the UI am using J query to add text boxes to allow the user to enter many names and corresponding email-ids. On submit I just want to access all the name and emails( multiple values) in my controller. Now I just need a help. Is there a way to create a hash of values with corresponding name and eamil some what like this. {"name1" => "eamil1","name2" => "eamil2" } ...
Pls help me out in this.
You can use 'fields_for' tag and pass a name followed by [] and a form built as shown below will send an array of hash values.
<%= fields_for :"names[]", User.new do |builder| %>
<%=builder.text_field :name%>
<%=builder.text_field :name%>
<%=builder.text_field :name%>
<%=builder.submit%>
<% end %>
On submitting the form generated by the above code, the params hash will contain names= [ {"name"=> "..."}, {"name" => "..."}, {"name" => "..."}]
With you Javascript code, you should generate some HTML input like:
<input type="text" name="invited_persons[0][name]" />
<input type="email" name="invited_persons[0][email]" />
<input type="text" name="invited_persons[1][name]" />
<input type="email" name="invited_persons[1][email]" />
Thanks to the numbers used as scope, the generated params will be like:
{
'invited_persons' => {
'0' => {
'name' => 'foo',
'email' => 'foo#foo.foo'
},
'1' => {
'name' => 'bar',
'email' => 'bar#bar.bar'
}
}
}
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 would like to use the form_for helper multiple times for the same model in the same page. But the input fields use the same ID attribute (in the HTML), so clicking on the label of a field in another form will select the same input in the first form.
Is there a solution besides settings all attributes manually via :for => "title_#{item.id}" and :id => "title_#{item.id}"?
Using Rails 3.0.9
You can use :namespace => 'some_unique_prefix' option. In contrast to :index, this will not change the value used in the name attribute.
It's also possible to use an array, e.g. when you have nested forms or different forms that happen to have some fields in common: :namespace => [#product.id, tag.id] or :namespace => [:product, #product.id]
I found the answer myself, one can pass a :index option to form_for. That string will be used in the id and for attributes:
<%= form_for #person, :index => #person.id do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
will parse
<form accept-charset="UTF-8" action="/person/11" class="edit_person" id="edit_person_11" method="post">
<!-- Hidden div for csrf removed -->
<label for="person_11_name">Name</label>
<input id="person_11_name" name="person[11][name]" size="30" type="text" />
<input name="commit" type="submit" value="Update Person" />
</form>
Notice it'll change the name of the inputs as well.
I believe you can add this param:
:html => { :id => 'id_i_want' }
I'm trying to create an ultra simple paypal custom integration with rails. I'm following Ryan Bates Railscast #141 on this subject and I've simplified it even further. If you have experience with super simple paypal integration, any advice would be appreciated!
I'm attempting to pass everything through my account model. A proof-of-concept.
def paypal_url(return_url)
values = {
:business => 'jwade_1268181180_biz#gmail.com',
:cmd => '_cart',
:upload => 1,
:return => return_url,
:invoice => 2,
:amount => 7,
:item_name => 'Membership',
:item_number => 1,
:quantity => 1
}
"https://www.sandbox.paypal.com/cgi-bin/webscr?" + values.to_query
end
and of course I create a link:
<%= link_to "Checkout", #account.paypal_url(accounts_path) %>
The Paypal detects an error: "Your shopping cart is empty", which is strange because I can see everything my model passes in the URL:
https://www.sandbox.paypal.com/cgi-bin/webscr?amount=7&business=jwade_1268181180_biz#gmail.com&cmd=_cart&invoice=&item_name=Barcoden+Membership&item_number=1&quantity=1&return=/accounts&upload=1
I've found that following the railscast results in that empty cart error message.
Try creating a form to replace the link like:
<div>
<%= form_tag 'https://www.sandbox.paypal.com/cgi-bin/webscr' do %>
<input type="hidden" name="cmd" value="_cart">
<input type="hidden" name="upload" value="1">
<input type="hidden" name="business" value="Your sandbox biz Account">
<input type="hidden" name="item_name_1" value="Some Name">
<input type="hidden" name="amount_1" value="100">
<input type="submit" value="PayPal">
<% end %>
</div>
That will work. Looks that the cart is not created unless you use a post request.
Using :method => :post in the link_to helper will not work.
You can use the button_to helper to create a mini form and replace the link_to in the railcast.
To answer we need to have a closer look at your code.
But perhaps this can help you: A Testable PayPal IPN with Rails 2.3