Rails 6 添加具有嵌套属性的连接模型记录

Rails 6 Adding Join Model Records with Nested Attributes

我有三个相关模型:PizzaItem、PizzaItemTopping 和 Topping,我正在尝试构建一个表单,它将仅为用户选择的浇头选项创建 PizzaItemTopping 记录。

通常我会做这样的事情来选择嵌套字段:

<%= form_with(model: @pizza_item) do |f| %>
  # my form fields

  <%= f.collection_check_boxes :topping_ids, @toppings, :id, :name %>
<% end %>

这很好用并且只添加了选定的配料,但我的 PizzaItemTopping 模型中有一个 'quantity' 字段,我希望用户能够对其进行自定义。所以我尝试了这个:

 <% @toppings.each do |topping| %>
   <%= form.fields_for :pizza_item_toppings do |f| %>
     <%= f.number_field :quantity, value: 0, id: nil %>
     <%= f.hidden_field :topping_id, value: topping.id, id: nil %>
   <% end %>
 <% end %>

但这将为存在的每个浇头创建一个 PizzaItemTopping 记录,这是不理想的。有没有办法让它只创建用户选择的记录,或者数量为0的记录?

这是我目前的解决方法,但我正在寻求有关更好方法的建议。

 # pizza_items_controller.rb
 @pizza_item = @order.pizza_items.new(pizza_item_params)

# Do not save toppings if their quantities are 0
@pizza_item.pizza_item_toppings.each do |x| 
  @pizza_item.pizza_item_toppings.delete(x) if x.quantity == 0 
end

  
class PizzaItem < ApplicationRecord
  # ...
  accepts_nested_attribute_for :pizza_item_toppings, 
    reject_if: ->{ |attributes| attributes['quantity'] == 0 }
end

使用 reject_if: 选项静默忽略任何新的记录散列,如果它们未能通过您的标准。

参见Active Record Nested Attributes