Verification problems


#1

Hello,

Hope this isn’t a newbie question - but I don’t seem to be able to find
relevent information elsewhere.

I am having trouble getting the following to work:
Schema

ActiveRecord::Schema.define(:version => 1) do

create_table “authors”, :force => true do |t|
t.column “name”, :string
end

create_table “books”, :force => true do |t|
t.column “title”, :string
t.column “author_id”, :integer
end

create_table “catalogs”, :force => true do |t|
t.column “author_id”, :integer
t.column “book_id”, :integer
end

Models

class Author < ActiveRecord::Base
has_many :book

validates_uniqueness_of :name
end
class Book < ActiveRecord::Base
belongs_to :author
has_many :catalog

validates_presence_of :author, :message => “doesn’t exist!”
validates_associated :author

Each book title must be unique to each author.

def validate
if Book.find_by_title_and_author_id(self.title, self.author_id)
errors.add(:title, “(#{self.title}) already exists for this author
(#{self.author.name})”)
end
end
end
class Catalog < ActiveRecord::Base
belongs_to :book

validates_presence_of :book
validates_associated :book
end

NOTE: The above is a contrived example to simplify the problem (in
reality the Catalogs table has other data associated with it).

The problem is that you can add authors and books, and all the
validation works like a charm (including checking the uniqueness across
multiple columns for a book), but when I try to add something to the
catalog, it is trying to validate the book model again and fails on the
Book.find_by_title_and_author_id() as the book obviously already exists.

Why is rails trying to revalidate the Book model when I am adding
something to the Catalog (it isn’t a save or update to Book is it?), am
I doing something wrong by checking uniqueness across multiple columns
in the model (if I remove it all works, but then I end up with duplicate
books).

Regards

Glenn


#2

Glenn wrote:

books).
Perhaps you want either:

   validates_associated :book, :on => :create

or
def validate_on_create

We develop, watch us RoR, in numbers too big to ignore.


#3

Each book title must be unique to each author.

def validate
if Book.find_by_title_and_author_id(self.title, self.author_id)
errors.add(:title, “(#{self.title}) already exists for this author
(#{self.author.name})”)
end
end

This can be written as
validates_uniqueness_of :title, :scope => ‘author_id’

See
http://api.rubyonrails.com/classes/ActiveRecord/Validations/ClassMethods.html#M000685
for details.

-Ben


#4

Benjamin S. wrote:

Each book title must be unique to each author.

def validate
if Book.find_by_title_and_author_id(self.title, self.author_id)
errors.add(:title, “(#{self.title}) already exists for this author
(#{self.author.name})”)
end
end

This can be written as
validates_uniqueness_of :title, :scope => ‘author_id’

See
http://api.rubyonrails.com/classes/ActiveRecord/Validations/ClassMethods.html#M000685
for details.

-Ben

Perfect - it works. Thanks for the tip.

Regards

Glenn