问题
I have a has_many :through form where I can't get an extra attribute to post to the database. I'm fouling up the parameter name somewhere. I can get the foreign keys to post but I have another attribute that I'm trying to track in the join table. Keep in mind this is a 100% ajax based form. Here's what I know
Edit: After researching similar issues, I understand I'm supposed to build the form attributes, but the code I've found doesn't work for some reason. Here are some resources.
http://railsforum.com/viewtopic.php?id=20203
Rails 3, nested multi-level forms and has_many through
What I don't understand is that attaching the product_ids is built into rails. Those values post. Why is it hard to attach the quantity_shipped attribute to that array?
Models and Relationships
Shipment has_many :products :through => :product_shipments
Product has_many :shipments :through => :product_shipments
ProductShipments belongs_to :shipment, belongs_to :product
ProductShipments table
t.integer :shipment_id
t.integer :product_id
t.integer :qty_shipped <-- This is the Problem Child
This partial is looped through a few times displaying all the products from a certain vendor. It generates an array for the product_ids and another for the product_shipments quantities.
_product_shipments.html.erb.
<div id="product_shipments_container">
<h3>Assign Products to Ship</h3>
<ul class="product_shipments" id="product_shipments">
<% Product.by_client(@client_id).each do |product| %>
<%= content_tag_for :li, product, :value => product.id do %>
<%= hidden_field_tag("shipment[product_ids][]", product.id) %>
<%= product.product_name %><%= text_field_tag("product_shipments[qty_shipped]")%> <--This is where the issue lies
<% end %>
<% end %>
</ul>
</div>
This is the relevant POST data when the form is submitted
"product_ids"=>["1", "3"]}, "product_shipments"=>{"qty_shipped"=>["32", "23"]}
This is sql that is sent to the database
INSERT INTO `product_shipments` (`product_id`, `qty_shipped`, `shipment_id`)
VALUES (1, NULL, 155)
INSERT INTO `product_shipments` (`product_id`, `qty_shipped`, `shipment_id`)
VALUES (3, NULL, 155)
Here is the action in my controller
def create
@shipment = Shipment.new(params[:shipment])
@product_shipments = @shipment.product_shipments.build(params[:product_shipments])
[:qty_shipped]) <- not correct, but it's what i got so far if @shipment.save respond_with @shipment, :location => shipments_url else flash[:notice]= "Not saved" end end
Here's the last issue I'm having.
TypeError (can't convert Symbol into Integer):
app/controllers/shipments_controller.rb:24:in `[]'
app/controllers/shipments_controller.rb:24:in `create'
GOT IT. After making the changes with the correct answer below. I was able to correct the controller to the following
@product_shipments = @shipment.product_shipments.build(params[:product_shipments])
回答1:
The simplest solution is that you need to generate an array of hashes that looks like
:product_shipments=>[{:product_id=>1, :qty_shipped=>32},{:product_id=>3, :qty_shipped=>23}]
instead of two sets of hashes :shipment=>{:product_ids=>[1,3]}
and :product_shipments=>[:qty_shipped=>[32,23]]
.
To do this, change your view code to
<%= hidden_field_tag("product_shipments[][product_id]", product.id) %>
<%= product.product_name %><%= text_field_tag("product_shipments[][qty_shipped]")%>
Then your controller action should work as is.
回答2:
Your 'create' action can be as simple as
def create
@shipment = Shipment.new(params[:shipment])
if @shipment.save
# success
else
# failure
end
end
if you use nested attributes to create shipment_products through the new shipment record. To do this, add the following to the Shipment model
class Shipment
attr_accessible :shipment_products_attributes
accepts_nested_attributes_for :shipment_products
end
By using fields_for
in the view, this will allow a shipment to accept params[:shipment][:shipment_products_attributes]
and pass these on to its shipment_products.
In your new action, you could do something like
def new
@shipment = Shipment.new
# collect the ids of the products you want to create shipment products for
@shipment.shipment_products.build([{:product_id=> ...},{:product_id=> ...}, ...])
end
so that in the form you could do something like
<%= form_for @shipment, :remote => true do |f|%>
...
...
<ul>
<%= f.fields_for :shipment_products do |sp_f| %>
<li>
<%= sp_f.text_field :qty_shipped %>
<%= sp_f.hidden_field :product_id %>
</li>
<% end %>
</ul>
<% end %>
来源:https://stackoverflow.com/questions/11199572/rails-3-2-has-many-through-form-submission