I''m trying to write a plugin which adds some new logic to the validate method of an ActiveRecord model. However, I still want the user to be able to define their own validate method in the model, and to call that as well as my new validate method. What''s happening now is if I define a validate method and the user defines a validate method as well, the validate method defined by the user will be called and the method in my plugin will not be called. I''ve tried to use alias_method to install my validate method in the place of the previous validate method, while still allowing me to call the original method as follows: alias_method :orig_validate, :validate alias_method :validate, :new_validate but when I place this after my validate method definition in my plugin, I get the following error when starting my server: undefined method `validate'' for module `AttachmentHandler::InstanceMethods'' I need to instruct rails that I''m redefining the validate method from ActiveRecord::Validations::ClassMethods but I don''t know how to do this. My end goal is to be able to add some conditions that a model must satisfy before being saved, and if it doesn''t pass these conditions, then I need to add errors to the object. If there''s a better way to do this than overriding validate, that would also be an option.. But right now, I''m completely stuck and can''t figure this out. Any help would be greatly appreciated. Thanks, Mike --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Mark Reginald James
2007-Aug-24 12:41 UTC
Re: Chaining validate method in a plugin, completely stumped
Mike Garey wrote:> My end goal is to be able to add some conditions that a model must > satisfy before being saved, and if it doesn''t pass these conditions, > then I need to add errors to the object. If there''s a better way to > do this than overriding validate, that would also be an option.. But > right now, I''m completely stuck and can''t figure this out. Any help > would be greatly appreciated. Thanks,How about adding a before_validation or after_validation callback. -- We develop, watch us RoR, in numbers too big to ignore. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Mike Garey
2007-Aug-24 22:27 UTC
Re: Chaining validate method in a plugin, completely stumped
On 8/24/07, Mark Reginald James <mrj-bzGI/hKkdgQnC9Muvcwxkw@public.gmane.org> wrote:> > Mike Garey wrote: > > > My end goal is to be able to add some conditions that a model must > > satisfy before being saved, and if it doesn''t pass these conditions, > > then I need to add errors to the object. If there''s a better way to > > do this than overriding validate, that would also be an option.. But > > right now, I''m completely stuck and can''t figure this out. Any help > > would be greatly appreciated. Thanks, > > How about adding a before_validation or after_validation callback.if I use before_validation, the errors that I add are not carried through to when the validate method is called. If I return false from my before_validation method, the error messages added are available, but the validate method is not called (I guess returning false in before_validate halts the filter chain). If I use after_validation, the errors are added to the object, but the object is still allowed to be saved, even if I return false in after_validation. So it doesn''t look like I can use the before/after validation callbacks (and also, are these callbacks chained? ie if I defined my own before/after validation, and the user defines their own as well, won''t their definition override mine?) Thanks, Mike --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Mark Reginald James
2007-Aug-24 23:24 UTC
Re: Chaining validate method in a plugin, completely stumped
Mike Garey wrote:> if I use before_validation, the errors that I add are not carried > through to when the validate method is called. If I return false from > my before_validation method, the error messages added are available, > but the validate method is not called (I guess returning false in > before_validate halts the filter chain). If I use after_validation, > the errors are added to the object, but the object is still allowed to > be saved, even if I return false in after_validation.Yes, you''re right. Neither before_validation nor after_validation will give you what you want.> So it doesn''t look like I can use the before/after validation > callbacks (and also, are these callbacks chained? ie if I defined my > own before/after validation, and the user defines their own as well, > won''t their definition override mine?)No, callbacks are properly chained. You can get your alias_method calls to work if you call them on the user class after your module has been included, either in the module "included" method or after the include statement in your capability-adding method. -- We develop, watch us RoR, in numbers too big to ignore. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Mike Garey
2007-Aug-24 23:49 UTC
Re: Chaining validate method in a plugin, completely stumped
On 8/24/07, Mark Reginald James <mrj-bzGI/hKkdgQnC9Muvcwxkw@public.gmane.org> wrote:> > Mike Garey wrote: > You can get your alias_method calls to work if you call them > on the user class after your module has been included, either in > the module "included" method or after the include statement > in your capability-adding method.yeah, I noticed that works fine, but since this is a plugin, I wanted to make this as invisible as possible.. Requiring the user to add the alias_method_chain calls after they define their own validate method is more obtrusive than I wanted. Since this is the ruby/rails world, I figured there would have to be a better way, but unfortunately I can''t figure it out. It''s a bit of a catch-22.. I can''t use alias_method in my plugin, since the plugin is loaded before the entire User class is loaded, which means that the validate method isn''t available to be aliased.. I wish there was a way of telling rails to alias the method regardless, under the assumption that the method will be available. Or to figure out some other way to hook into the validation class. Thanks for the response Mark, Mike --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Mark Reginald James
2007-Aug-25 03:03 UTC
Re: Chaining validate method in a plugin, completely stumped
Mike Garey wrote:> On 8/24/07, Mark Reginald James <mrj-bzGI/hKkdgQnC9Muvcwxkw@public.gmane.org> wrote: >> Mike Garey wrote: >> You can get your alias_method calls to work if you call them >> on the user class after your module has been included, either in >> the module "included" method or after the include statement >> in your capability-adding method. > > yeah, I noticed that works fine, but since this is a plugin, I wanted > to make this as invisible as possible.. Requiring the user to add the > alias_method_chain calls after they define their own validate method > is more obtrusive than I wanted. Since this is the ruby/rails world, > I figured there would have to be a better way, but unfortunately I > can''t figure it out. > > It''s a bit of a catch-22.. I can''t use alias_method in my plugin, > since the plugin is loaded before the entire User class is loaded, > which means that the validate method isn''t available to be aliased.. > I wish there was a way of telling rails to alias the method > regardless, under the assumption that the method will be available. > Or to figure out some other way to hook into the validation class.By putting it in your capability-adding method i meant: module ActsAsMike module ClassMethods ... end module InstanceMethods def new_validate ... validate # Call AR::B validate or UserClass validate end ... end end class ActiveRecord::Base def self.acts_as_mike extend ActsAsMike::ClassMethods include ActsAsMike::InstanceMethods alias_method :orig_validate, :validate alias_method :validate, :new_validate end end -- We develop, watch us RoR, in numbers too big to ignore. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Mike Garey
2007-Aug-29 21:29 UTC
Re: Chaining validate method in a plugin, completely stumped
On 8/24/07, Mark Reginald James <mrj-bzGI/hKkdgQnC9Muvcwxkw@public.gmane.org> wrote:> By putting it in your capability-adding method i meant: > > module ActsAsMike > module ClassMethods > ... > end > > module InstanceMethods > def new_validate > ... > validate # Call AR::B validate or UserClass validate > end > ... > end > end > > class ActiveRecord::Base > def self.acts_as_mike > extend ActsAsMike::ClassMethods > include ActsAsMike::InstanceMethods > alias_method :orig_validate, :validate > alias_method :validate, :new_validate > end > end >thanks for the respone Mark, I seem to be getting closer, as I can now override the default validate method and still call the original validate method from within new_validate. The only problem is that the user _must_ place the ''acts_as_validatable'' class method after their validate method, otherwise the alias_method call won''t override their method, and my new_validate method will not be called. Ideally, I''d like to avoid having the restriction that the user must call acts_as_validatable after they define their own validate method - is there any way to get around this? Here''s the minimal code for the plugin I''ve got right now: acts_as_validatable.rb module ActsAsValidatable module InstanceMethods def new_validate logger.warn("NEW VALIDATE CALLED") orig_validate end end end # ActsAsValidatable class ActiveRecord::Base def self.acts_as_validatable include ActsAsValidatable::InstanceMethods alias_method :orig_validate, :validate alias_method :validate, :new_validate end end the following works perfectly (the logger shows both "NEW VALIDATE CALLED" and then "ORIGINAL VALIDATE CALLED") my_class.rb class MyClass < ActiveRecord::Base def validate logger.warn("ORIGINAL VALIDATE CALLED") end acts_as_validatable end the following doesn''t work (the only thing that gets logged is "ORIGINAL VALIDATE CALLED"): my_class.rb class MyClass < ActiveRecord::Base acts_as_validatable def validate logger.warn("ORIGINAL VALIDATE CALLED") end end Thanks again for the help, Mike --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---