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:
选项静默忽略任何新的记录散列,如果它们未能通过您的标准。
我有三个相关模型: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:
选项静默忽略任何新的记录散列,如果它们未能通过您的标准。