首先,我要说这可能也是一个建模问题,我对模型建议持开放态度。
用例: 我有一个表单,需要允许用户在他们的帖子类别中选择一个复选框。如果没有符合他们帖子的类别,则勾选其他类别将显示一个文本字段,供用户添加自定义类别。这适用于创建和更新嵌套模块。
数据库建模
class CreateCategories < ActiveRecord::Migration
def change
create_table :categories do |t|
t.string :name, null: false
t.timestamps null: false
end
reversible do |dir|
dir.up {
Category.create(name: 'Hats')
Category.create(name: 'Shirts')
Category.create(name: 'Pants')
Category.create(name: 'Shoes')
Category.create(name: 'Other')
}
end
create_table :categorizations, id: false do |t|
t.belongs_to :post, index: true, null: false
t.belongs_to :category, index: true, null: false
t.string :value
end
end
end
应用程序模型
class Post < ActiveRecord::Base
has_many :categorizations
accepts_nested_attributes_for :categorizations, allow_destroy: true
has_many :categories, through: :categorizations
accepts_nested_attributes_for :categories
end
class Category < ActiveRecord::Base
has_many :posts
end
控制器:
def update
if @post.update(post_params)
flash.now[:success] = 'success'
else
flash.now[:alert] = @post.errors.full_messages.to_sentence
end
render :edit
end
private
def set_post
@post = Post.find(params[:id])
(Category.all - @post.categories).each do |category|
@post.categorizations.build(category: category)
end
@post.categorizations.to_a.sort_by! {|x| x.category.id }
end
def post_params
params.require(:post).permit(:name, :description,
categorizations_attributes: [ :category_id, :value, :_destroy],
)
end
查看:
= f.fields_for :categorizations do |ff|
= ff.check_box :_destroy, { checked: ff.object.persisted? }, '0', '1'
= ff.label :_destroy, ff.object.category.name
= ff.hidden_field :category_id
= ff.text_field :value if ff.object.category.other?
然而,使用上述解决方案后,我在保存时仍然遇到了重复记录错误。不确定为什么会发生这种情况?是否有更好的方法来解决这个问题?