【问题标题】:Rails 3.2 has_many through form submissionRails 3.2 has_many 通过表单提交
【发布时间】:2012-06-27 07:30:25
【问题描述】:

我有一个 has_many :through 表单,我无法获得额外的属性来发布到数据库。我在某处弄脏了参数名称。我可以获取要发布的外键,但我有另一个要在连接表中跟踪的属性。请记住,这是一个 100% 基于 ajax 的表单。这是我所知道的

编辑: 在研究了类似的问题之后,我知道我应该构建表单属性,但是我发现的代码由于某种原因不起作用。这里有一些资源。

http://railsforum.com/viewtopic.php?id=20203

Rails 3, nested multi-level forms and has_many through

我不明白的是,附加 product_ids 是内置在导轨中的。这些价值观发布。为什么很难将 quantity_shipped 属性附加到该数组?

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

此部分循环显示来自某个供应商的所有产品几次。它为 product_ids 生成一个数组,为 product_shipments 数量生成另一个数组。

_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>

这是提交表单时的相关POST数据

"product_ids"=>["1", "3"]}, "product_shipments"=>{"qty_shipped"=>["32", "23"]}

这是发送到数据库的sql

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)

这是我的控制器中的操作

def create
 @shipment = Shipment.new(params[:shipment])

 @product_shipments = @shipment.product_shipments.build(params[:product_shipments])

[:qty_shipped]) shipping_url 别的 flash[:notice]= "未保存" 结尾 结束

这是我遇到的最后一个问题。

TypeError (can't convert Symbol into Integer):
  app/controllers/shipments_controller.rb:24:in `[]'
  app/controllers/shipments_controller.rb:24:in `create'

知道了。使用下面的正确答案进行更改后。我能够将控制器更正为以下内容

@product_shipments = @shipment.product_shipments.build(params[:product_shipments])

【问题讨论】:

  • 你的意思是写text_field_tag("shipment_products[qty_shipped][]")
  • 这似乎没有什么不同。它仍然输入一个空值
  • 您的模型有has_many :shipment_productsaccepts_nested_attributes_for :shipment_products 吗?为什么不使用fields_for?你知道simple_formformtastic吗?如果您想动态添加货件,请查看cocoon gem。
  • 是的,它们具有上面列出的关联。我可以使用 fields_for 或 text_field_tag,我已经接受了_nested_attributes。
  • 您能否也发布相关的控制器操作(您尝试创建新货件的位置)?

标签: jquery ruby-on-rails ruby-on-rails-3.1 has-many-through


【解决方案1】:

最简单的解决方案是你需要生成一个哈希数组,看起来像

:product_shipments=>[{:product_id=>1, :qty_shipped=>32},{:product_id=>3, :qty_shipped=>23}]

而不是两组哈希 :shipment=&gt;{:product_ids=&gt;[1,3]}:product_shipments=&gt;[:qty_shipped=&gt;[32,23]]

为此,请将您的视图代码更改为

<%= hidden_field_tag("product_shipments[][product_id]", product.id) %>
<%= product.product_name %><%= text_field_tag("product_shipments[][qty_shipped]")%>

那么您的控制器操作应该按原样工作。

【讨论】:

  • 好消息是哈希现在看起来不错。控制器动作需要调整。我在答案末尾发布了错误。
  • 这修复了它。 @product_shipments = @shipment.product_shipments.build(params[:product_shipments])
【解决方案2】:

您的“创建”操作可以很简单

def create
  @shipment = Shipment.new(params[:shipment])

  if @shipment.save
    # success
  else
    # failure
  end
end

如果您使用嵌套属性通过新的发货记录创建 shipping_products。为此,请将以下内容添加到 Shipment 模型中

class Shipment
  attr_accessible :shipment_products_attributes
  accepts_nested_attributes_for :shipment_products
end

通过在视图中使用 fields_for,这将允许货件接受 params[:shipment][:shipment_products_attributes] 并将这些传递给它的 shipping_products。

在你的新动作中,你可以做类似的事情

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

这样你就可以在表单中做类似的事情

<%= 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 %>

【讨论】:

  • 在您的回答中,只有在您知道要分配多少产品的情况下,新操作才会起作用。如果你不知道怎么办?部分循环几次,生成可供某个供应商使用的所有产品,因此产品的数量不是有限的。部分中的 shipping_products 必须是一个数组
  • 只是另一个简短的说明。 ship_id 和 product_id 正确发布到数据库。这是丢失的数量。
  • 你究竟是如何遍历部分的?
  • 顺便说一句,如果您在新操作中将这些 shipping_products 构建到货件中,fields_for 将在此处为您提供一个 shipping_products 数组,如上所示。
  • 对不起,这是很多信息。我非常感谢您的帮助@cdesrosiers
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-06
  • 2017-01-09
  • 2020-05-01
  • 1970-01-01
  • 2012-05-07
相关资源
最近更新 更多