Search code examples
ruby-on-rails-3validationactivemodel

Is there an ActiveModel validation for association consistency


By example:

  • A Place belongs to a User.
  • An Event belongs to a User.
  • An Event belongs to (but is not required to have) a Place.

I'd like to validate that an Event's Place always has the same User as the Place itself.

Validations of this form seem fairly common, yet I always end up writing my own validator. I'll include my version below for completeness, but I feel there should be a convention.


Solution

  • If an Event always has the same User as the Place, perhaps you should be modelling the association like this:

    User
      has_many :places
      has_many :events, through: :places
    
    Place
      has_many :events
      belongs_to :user
    
    Event
      belongs_to :place
      has_one :user, through: :place
    

    Then you don't need a validation; the structure of the associations enforces that for free.

    Update: Although Place is optional, I would still structure the associations like this! It sounds like you might want to break out the Null Object pattern. There are several ways you could implement it; perhaps Single Table Inheritance would be suitable.

    Essentially, you would create a subclass NullPlace < Place, which would have some special behaviour (its name might be some placeholder like "not specified"), but in terms of the associations it would behave just like a regular Place so no validations required!