被破坏的嵌套模型轨道中的 validates_uniqueness_of
我有一个项目模型,它接受任务的嵌套属性。
class Project < ActiveRecord::Base
has_many :tasks
accepts_nested_attributes_for :tasks, :allow_destroy => :true
end
class Task < ActiveRecord::Base
validates_uniqueness_of :name
end
任务模型中的唯一性验证在更新项目时会出现问题。
在编辑项目时,我删除了任务 T1,然后添加了同名 T1 的新任务,唯一性验证限制了项目的保存。
params hash 看起来像
task_attributes => { {"id" =>
"1","name" => "T1", "_destroy" =>
"1"},{"name" => "T1"}}
任务验证在销毁旧任务之前完成。因此验证失败。知道如何验证以使其不认为任务被破坏吗?
I have a Project model which accepts nested attributes for Task.
class Project < ActiveRecord::Base
has_many :tasks
accepts_nested_attributes_for :tasks, :allow_destroy => :true
end
class Task < ActiveRecord::Base
validates_uniqueness_of :name
end
Uniqueness validation in Task model gives problem while updating Project.
In edit of project i delete a task T1 and then add a new task with same name T1, uniqueness validation restricts the saving of Project.
params hash look something like
task_attributes => { {"id" =>
"1","name" => "T1", "_destroy" =>
"1"},{"name" => "T1"}}
Validation on task is done before destroying the old task. Hence validation fails.Any idea how to validate such that it doesn't consider task to be destroyed?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
Andrew France 在此线程中创建了一个补丁,其中验证是在内存中完成的。
Andrew France created a patch in this thread, where the validation is done in memory.
据我了解,Reiner 关于在内存中进行验证的方法对于我来说并不实用,因为我有很多“书”,500K 并且还在不断增长。如果你想把一切都记在记忆里,那将会是一个很大的打击。
我想出的解决方案是:
通过将以下内容添加到迁移文件中,将唯一性条件放入数据库中(我发现这始终是一个好主意,因为根据我的经验,Rails 并不总是做得很好)在 db/migrate/ 中:
在控制器中,将 save 或 update_attributes 放置在事务中,并拯救数据库异常。例如,
结束
As I understand it, Reiner's approach about validating in memory would not be practical in my case, as I have a lot of "books", 500K and growing. That would be a big hit if you want to bring all into memory.
The solution I came up with is to:
Place the uniqueness condition in the database (which I've found is always a good idea, as in my experience Rails does not always do a good job here) by adding the following to your migration file in db/migrate/:
In the controller, place the save or update_attributes inside a transaction, and rescue the Database exception. E.g.,
end
Rainer Blessing 的回答很好。
但如果我们能够标记哪些任务是重复的,那就更好了。
Rainer Blessing's answer is good.
But it's better when we can mark which tasks are duplicated.
对于 Rails 4.0.1,此问题被标记为已通过此拉取请求修复,https://github .com/rails/rails/pull/10417
就我个人而言,这对我来说仍然不起作用,所以我认为它还没有完全解决。
For Rails 4.0.1, this issue is marked as being fixed by this pull request, https://github.com/rails/rails/pull/10417
Personally this still doesn't work for me, so I don't think it's completely fixed yet.
参考 这个
你为什么不使用 :scope
这将为每个项目创建独特的任务。
Ref this
Why don't you use :scope
this will create unique Task for each project.