Quick ActiveRecord Tip: Adding Validations From a MixIn
As your domain model grows in complexity, you may want to factor out some common traits and behaviour into a MixIn. For the Java crowd out there, mixins are just a much simpler way to do AOP.
While adding instance methods via a MixIn is straightforward, adding constraints to your model requires to execute code in the scope of the class in which you include the module. It took me a while to get this one right so I thought I'd share:
module Discountable def self.included(base) base.class_eval do validates_inclusion_of :discount_type, :in => %w{ None Percentage Absolute } validates_numericality_of :discount_value end end def compute_discount(price) # ... end # ... end
Now in your actual ActiveRecord class:
class OrderItem < ActiveRecord::Base # Associations belongs_to :order belongs_to :product # Validations validates_presence_of :quantity, :unit_price validates_numericality_of :quantity, :unit_price # Add discountable properties and constraints include Discountable end
The same method can be used to declare associations or activate any kind of "acts as" behaviors.
I love this game.

