how to define/attach rails validations in multiple generations of modules -
i've found way make work, curious better way / rails 3 way. (i'm using 2.3.5 still, hope migrate around new year's.)
the situation: i've got 2 layers of module inheritance, second layer gets mixed rails model. both modules define validation methods , i'd both of them attach validations base class, because of 2 levels of inheritance, following doesn't work:
def self.included(base) base.validate :yadda_yadda end
when module included module, interpreter grinds screeching halt because modules don't know activerecord::validations
. including validations module begs question of "where save
?" alias_method
.
the following works, long remember call super
whenever override validate()
. don't trust myself or future maintainers remember that, i'd use validate :yadda_yadda
idiom instead, if possible.
module grandpa def validate must_be_ok end def must_be_ok errors.add_to_base("#{self} wasn't ok") end end module dad include grandpa def validate super must_be_ok_too end def must_be_ok_too errors.add_to_base("#{self} wasn't ok either") end end class kid < activerecord::base include dad validate :must_be_ok_three def must_be_ok_three errors.add_to_base("#{self} wasn't ok furthermore") end end
suggestions? tips rails 3 approach? don't think validations api has changed much.
i solved (when ran same problem, other validation).
short answer: can call send(:included, base) on module want bring in. within higher-up included() definition, need check whether base class or module.
why ever want this? well, i've got modules extract common functionality out of models. instance, module hasallocable
sets polymorphic belongs_to
relationship, , getter/setter pair virtual attribute. have module needs pull in hasallocable
, spare base classes having remember it.
i'd interested know whether smells funny anyone. haven't seen on web, wonder if multiple layers of model inheritance more of antipattern.
module grandpa def self.included(base) if base.kind_of?(class) base.validate :must_be_ok end end end module dad include grandpa def self.included(base) if base.kind_of?(class) # can #base.send(:include, grandpa) # can grandpa.send(:included, base) # not invoke grandpa.included(kid) #super(base) base.validate :must_be_ok_too end end end class kid < activerecord::base include dad validate :must_be_ok_three end
Comments
Post a Comment