通过使用标记 select2 创建的动态 has_many
Dynamic has_many through creation with tagging select2
我有一个配方模型,has_many 设备通过配方设备设置如下:
class Recipe < ApplicationRecord
has_many :recipe_equipment, dependent: :destroy
has_many :equipment, through: :recipe_equipment
accepts_nested_attributes_for :recipe_equipment
end
class Equipment < ApplicationRecord
has_many :recipe_equipment
has_many :recipes, through: :recipe_equipment
end
class RecipeEquipment < ApplicationRecord
belongs_to :recipe
belongs_to :equipment
end
一切都很简单。然后在我的食谱表单中,我使用 select2 并启用了标签选项,这里是输入:
<div class="form-group">
<%= form.label :equipment_ids, "Equipment Needed" %>
<%= form.collection_select :equipment_ids, Equipment.all.order(:name), :id, :name, {:selected => recipe.recipe_equipment.map(&:equipment_id)}, { multiple: true } %>
</div>
和标准的select2初始化:
$('#recipe_equipment_ids').select2({
width: '100%',
maximumSelectionLength: 10,
tags: true});
所以这一切都按预期工作,除了当输入新设备时,它是作为文本而不是 ID 提交的(因为设备尚未创建并且没有 ID)
"equipment_ids"=>["", "7", "3", "Wok"]
所以在控制器中调用 create/update 之前寻找一种处理参数数组的方法,如果新设备尚不存在则创建新设备。不过不确定该怎么做。
所以在我 posted 之后就想通了,但我想 post 是其他人的答案。此外,这可能不是最好的解决方案,但它确实完成了工作并限制了对数据库的额外查询
所以我最终覆盖了 recipe.rb 文件中 equipment_ids 的默认访问器。因为它是潜在整数和字符串的混合体,所以检查它是否已经不是整数,然后使用 find_or_create_by!方法创建一个新的设备名称。然后将新 id 传递给数组并将其传递给 super.
def equipment_ids=(value)
equip = []
value.reject!(&:empty?).each do |e|
equip << (e.to_i != 0 ? e : Equipment.find_or_create_by!(name: e).id)
end
super(equip)
end
我有一个配方模型,has_many 设备通过配方设备设置如下:
class Recipe < ApplicationRecord
has_many :recipe_equipment, dependent: :destroy
has_many :equipment, through: :recipe_equipment
accepts_nested_attributes_for :recipe_equipment
end
class Equipment < ApplicationRecord
has_many :recipe_equipment
has_many :recipes, through: :recipe_equipment
end
class RecipeEquipment < ApplicationRecord
belongs_to :recipe
belongs_to :equipment
end
一切都很简单。然后在我的食谱表单中,我使用 select2 并启用了标签选项,这里是输入:
<div class="form-group">
<%= form.label :equipment_ids, "Equipment Needed" %>
<%= form.collection_select :equipment_ids, Equipment.all.order(:name), :id, :name, {:selected => recipe.recipe_equipment.map(&:equipment_id)}, { multiple: true } %>
</div>
和标准的select2初始化:
$('#recipe_equipment_ids').select2({
width: '100%',
maximumSelectionLength: 10,
tags: true});
所以这一切都按预期工作,除了当输入新设备时,它是作为文本而不是 ID 提交的(因为设备尚未创建并且没有 ID)
"equipment_ids"=>["", "7", "3", "Wok"]
所以在控制器中调用 create/update 之前寻找一种处理参数数组的方法,如果新设备尚不存在则创建新设备。不过不确定该怎么做。
所以在我 posted 之后就想通了,但我想 post 是其他人的答案。此外,这可能不是最好的解决方案,但它确实完成了工作并限制了对数据库的额外查询
所以我最终覆盖了 recipe.rb 文件中 equipment_ids 的默认访问器。因为它是潜在整数和字符串的混合体,所以检查它是否已经不是整数,然后使用 find_or_create_by!方法创建一个新的设备名称。然后将新 id 传递给数组并将其传递给 super.
def equipment_ids=(value)
equip = []
value.reject!(&:empty?).each do |e|
equip << (e.to_i != 0 ? e : Equipment.find_or_create_by!(name: e).id)
end
super(equip)
end