Rails 3.2 has_many through form submission

筅森魡賤 提交于 2019-11-28 07:11:25

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!