Validations on associated objects

Updated . Posted . Visible to the public.

Validations that need to access an associated object may lead to some trouble. Let's exemplify that using this example:

class Project < ActiveRecord::Base
   has_one :note
end

class Note < ActiveRecord::Base
   belongs_to :project
end

Now say we need a validation that ensures that a description is set (validates_presence_of :description) within Note but only if the Project has a flag called external set to true. The following code will lead to some problems as the associated object is not present when creating a new Project.

class Note < ActiveRecord::Base 
  validates_presence_of :description, :if => Proc.new { |note| note.project.description.present? }
...

This does not work when creating a new Project as the project is not yet associated to the note.
The solution is to use the trait attached and use it for Note the way our traits in Ruby Show archive.org snapshot are used:

class Note < ActiveRecord::Base 
  does 'sticky_errors'
...

Additionally you add the conditions for the validation to the parent class like this:

class Project < ActiveRecord::Base

  before_validation :ensure_description_present_for_external_notes

  def ensure_description_present_for_external_notes
    if note && note.description.blank? && external?
      note.add_sticky_error_on(:description, '^You need some description, honey!')
    end
  end

The trait will evaluate the error added by using add_sticky_error_on().

Thomas Eisenbarth
Last edit
License
Source code in this card is licensed under the MIT License.
Posted by Thomas Eisenbarth to makandra dev (2011-05-03 15:16)