从复选框构建数组时form_for的语法

时间:2012-01-13 11:55:14

标签: ruby-on-rails

我正在为Order对象创建一个表单,并且该订单包含许多Products,通过名为OrderProducts的连接表。所以,我们有这样的事情:

<% @order = Order.new %>
<% form_for @order do |f| %>
  <% @products.each do |product| %>
    ... want to iterate over products here to build up "order[product_ids][]", with one checkbox per product
  <% end %>
<% end %>

通常对于每个产品我会有一个check_box_tag,说

<%= check_box_tag "order[product_ids][]", product.id, @order.product_ids.include?(product.id) %>

但是,这一点,虽然工作正常,但总觉得有点像警察。有没有办法用f.check_box语法来做到这一点?重要提示 - 关于有问题的项目我在Rails 2.2.2中工作,因此在rails 2中工作的解决方案将是理想的。

4 个答案:

答案 0 :(得分:43)

Rails&lt; = 2.x (原创)

<% @products.each do |product| -%>

  <% fields_for 'product[]' , product do |product_fields| -%>

    [...]
    <%= product_fields.check_box :id %>

  <% end -%>

<% end -%>

Rails&gt; = 3.x (已更新)

<% @products.each do |product| -%>

  <%= fields_for 'product[]' , product do |product_fields| -%>

    [...]
    <%= product_fields.check_box :id %>

  <% end -%>

<% end -%>

答案 1 :(得分:31)

我知道作者正在寻找第2版的答案,但这是谷歌和我的最热门,但我会更新:

可以做到这一点(我使用的是4.0,不知道它有多远):

<%= form_for @order do |form| %>
  <%= form.collection_check_boxes(:product_ids, Product.all, :id, :labeling_method ) %>
<% end %>

了解更多信息:http://edgeapi.rubyonrails.org...

答案 2 :(得分:1)

多年来,我已经完成了许多多重复选框表单和不同的Rails版本。 Rails从来没有提供任何真正干净的方法来做到这一点,但你提出的“警察出局”解决方案是相当不错的不是吗?这是一条线,它是明确的,只要产品清单相当短,它就会充分发挥作用。

要回答您的具体问题,f.check_box将无法解决此问题。它只是check_box_tag的简写,但没有一个语义适用。如果你想使用Rails原生,我认为唯一的可能就是使用nested attributes。部分问题在于,没有一种明显的方法可以使这类事物发挥作用。 Rails核心经历了大量的计划和反馈,以提供嵌套属性,尽管它们看起来有点迟钝,但它们非常优雅地捕获了最常见的用例。但嵌套属性是在Rails 2.3中引入的,除此之外,它们还会引入相当多的概念开销,听起来它不需要复杂性。

还有一些插件可以为此提供帮助,虽然我很久没有使用过任何插件(实际上是Rails 2时代)。我的印象是,除非你有许多形式可以利用这种模式,否则它们也是过度杀伤。

简而言之,我认为你应该继续使用现有的解决方案。

答案 3 :(得分:-1)

formastic gem

check_boxes选项非常适合实现多个复选框

f.input :yourcolumn, :as => :check_boxes, :collection => your_collection