我的主要目标是在正确创建新记录后删除旧记录。我尝试使用#dup
方法将其分配给变量。请查看示例代码:
def my_method
old_items = @user.items.dup
new_items = @user.items.new(item_params) # one or more
# confusing part
old_items.destroy_all if new_items.save
end
我想要销毁old_items
但是当我创建new_items时,它们是old_items == new_items
。为什么重复#dup
在这里不起作用?我怎么能拆分和删除旧记录?我还尝试了一个事务(如果new_items无效则回滚),这也没有用。
答案 0 :(得分:3)
@RequestBody String userJson, Model model, BindingResult errors
这里复制了.dup
,它更多是对记录的延迟加载引用而不是记录本身。
因此,当您执行ActiveRecord::Relation
时,您仍在修改集合。
相反,你可以这样做:
new_item = @user.items.new(item_params)
但如果用户只能有一个项目,为什么要使用def my_method
new_item = @user.items.new(item_params)
if new_item.save
@user.items.where.not(id: new_item.id).destroy_all
end
end
而不是has_many
关系?
您还可以考虑使用nested attributes:
has_one
你可以这样做:
class User
has_many :items
accepts_nested_attributes_for :items, allow_destroy: true
end
class Item
belongs_to :user
end
此示例将删除第1项并创建名为User.find(1).update(items_attributes: [
{ id: 1, _destroy: "1" },
{ name: 'Bob' }
])
的新项目。这样可以轻松创建表单输入,让用户决定保留/销毁哪些记录。
答案 1 :(得分:0)
另一种解决方案是为名为“is_new”的每条记录使用布尔字段。
所有记录都是通过设置Bob
创建的,但在保存之前我们会找到旧记录并使用以下命令销毁它们:
is_new = true
或者如果你不需要销毁它们,则将它们设置为false。
答案 2 :(得分:-1)
def my_method
##create new and delete all except new one
new_item = @user.items.new(item_params)
##any condition that you want to compare
@user.items.where.not(:item_name=> new_item.name ).destroy_all
end
答案 3 :(得分:-1)
根据您想要的方式,有很多可能性。一种方法可能就是这个:
def my_method
old_items = get_old_items_ids
new_item = @user.items.new(item_params)
if new_item.save
old_items.delete_old_items
end
end
def get_old_items_ids
@user.items.pluck(:id)
end
def delete_old_items(old_item_ids)
Items.where(:id => old_item_ids).destroy_all
end
另一种方法是比较created_at的时间戳和之前创建的删除文件。