[英]In Rails, how to respect :scope when using validates_uniqueness_of in an embedded object form?
I have a Book model, which has_many Chapters (which belong_to a Book). 我有一个Book模型,它有很多章(属于一本书)。
I want to ensure uniqueness of Chapter titles, but only within the scope of a single book. 我想确保章节标题的唯一性,但只能在单本书的范围内。 The catch is that the form for creating chapters is embedded in the Book model's form (The Book model accepts_nested_attributes_for :chapters). 所要注意的是,用于创建章节的表单已嵌入到Book模型的表单中(Book模型accepts_nested_attributes_for:chapters)。
Within the Chapter model: 在章节模型中:
validates_uniqueness_of( :chapter_title, :scope => :book_id, :case_sensitive => false, :message => "No book can have multiple chapters with the same title.")
However, when I submit the Book creation form (which also includes multiple embedded Chapter forms), if the chapter title exists in another chapter for a different book, I fail the validation test. 但是,当我提交“书籍创建”表单(还包括多个嵌入的“章节”表单)时,如果该章节的标题存在于另一本书的另一章中,则我的验证测试将失败。
Book.create( :chapters => [ Chapter.new(:title => "Introduction"), Chapter.new(:title => "How to build things")
=> Book 1 successfully created
Book.create( :chapters => [ Chapter.new(:title => "Introduction"), Chapter.new(:title => "Destroy things")
=> Book 2 fails to validate
second_book = Book.create( :chapters => [ Chapter.new(:title => "A temporary Introduction title"), Chapter.new(:title => "Destroy things")
=> Book 2 succesfully created
second_book.chapters[0].title= "Introduction"
=> success
second_book.chapters.save
=> success
second_book.save
=> success
Can anyone shed some light on how to do this? 任何人都可以阐明如何执行此操作吗? Or why it's happening? 还是为什么会这样?
it's because Book gets Chapters which have book_id set to NULL, and it does not set their book_id before validation b/c it have no id at this step. 这是因为Book获取的book_id设置为NULL的章节,并且在验证b / c之前没有设置其book_id,因此在此步骤中没有id。
first solution is to use Book.build_chapter() method, but it will require a separate method call for each chapter 第一个解决方案是使用Book.build_chapter()方法,但是每章将需要单独的方法调用
second is to use accepts_nested_attributes_for and create a book like: 第二种是使用accepts_nested_attributes_for并创建一本书,例如:
book_attrs = {
:chapters_attributes => [
{ :title => 'Intro' },
{ :title => 'Core' },
{ :title => 'Outro'}
]
}
book = Book.create(book_attrs)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.