在Rails中,如何在嵌入对象表单中使用validates_uniqueness_of时尊重:范围?

时间:2010-05-28 19:12:45

标签: ruby-on-rails activerecord

我有一本书模型,其中有很多章节(属于一本书)。

我想确保章节标题的唯一性,但仅限于一本书的范围内。问题在于,创建章节的表单嵌入在Book模型的表单中(The Book model accepts_nested_attributes_for:章节)。

在章节模型中:

 
validates_uniqueness_of(
    :chapter_title, 
    :scope => :book_id,
    :case_sensitive => false,
    :message => "No book can have multiple chapters with the same title.")

但是,当我提交图书创建表格(其中还包括多个嵌入的章节表格)时,如果章节标题存在于另一章中,则表示我不通过验证测试。

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

任何人都可以了解如何做到这一点?或者为什么会这样?

1 个答案:

答案 0 :(得分:0)

这是因为Book获取了将book_id设置为NULL的章节,并且在验证之前它没有设置book_id b / c它在此步骤中没有id。

第一个解决方案是使用Book.build_chapter()方法,但每个章节都需要单独的方法调用

第二个是使用accepts_nested_attributes_for并创建一本书,如:

  book_attrs = {
    :chapters_attributes => [
      { :title => 'Intro' },
      { :title => 'Core' },
      { :title => 'Outro'}
    ]
  }

  book = Book.create(book_attrs)