简体   繁体   English

在Rails中,当以嵌入式对象形式使用validates_uniqueness_of时如何尊重:scope?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM