What's the right kind of validation to include for subordinate models? For example, let's say you've got books with chapters. The number of chapters per book is determined when the book is first created.
class Book < ActiveRecord::Base
has_many :chapters
def build_chapters(count)
(1..count).each do |i|
chapters.build(:sequence_number => i)
end
end
end
class Chapter < ActiveRecord::Base
belongs_to :book
validates_presence_of :book_id, :sequence_number
end
class BooksController < ApplicationController
def create
@book = Book.new(params[:book])
@book.build_chapters(4) #to simplify example, hardcode number of chapters
@book.save
# View-related code omitted for simplicity
end
end
When I run this I get one "chapters is invalid" error per chapter (4 errors when hard-coded like the example). Explicitly setting the :book_id in the build call doesn't help.
However, if I save the book before adding chapters it works, no errors. If I take out the validation in Chapter it works, no errors. But neither of those workarounds makes me happy. A book shouldn't be allowed to exist in the database without its chapters, and a chapter shouldn't be allowed to exist in the database without being linked to a book. What's the right way to enforce the relationship constraints?
I'm new to ruby and to rails, so it's entirely possible I'm just not thinking in rails-ese yet. Please edumacate me.