# Chaining validate method in a plugin, completely stumped

**URL:** <https://www.ruby-forum.com/t/chaining-validate-method-in-a-plugin-completely-stumped/112850>\
**Category:** Rails\
**Created:** [August 23, 2007, 9:20pm UTC](https://www.ruby-forum.com/t/chaining-validate-method-in-a-plugin-completely-stumped/112850 "2007-08-23T21:20:50Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![random52k](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@random52k](https://www.ruby-forum.com/u/random52k)\
**Post date:** [August 23, 2007, 9:20pm UTC](https://www.ruby-forum.com/t/chaining-validate-method-in-a-plugin-completely-stumped/112850/1 "2007-08-23T21:20:50Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![random52k](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@random52k](https://www.ruby-forum.com/u/random52k)\
**Post date:** [August 24, 2007, 2:42pm UTC](https://www.ruby-forum.com/t/chaining-validate-method-in-a-plugin-completely-stumped/112850/2 "2007-08-24T14:42:50Z")

</div>

Mike G. 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.

---

<div class="post-metadata">

**Author:** ![random52k](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@random52k](https://www.ruby-forum.com/u/random52k)\
**Post date:** [August 25, 2007, 12:28am UTC](https://www.ruby-forum.com/t/chaining-validate-method-in-a-plugin-completely-stumped/112850/3 "2007-08-25T00:28:49Z")

</div>

On 8/24/07, Mark Reginald J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 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

---

<div class="post-metadata">

**Author:** ![random52k](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@random52k](https://www.ruby-forum.com/u/random52k)\
**Post date:** [August 25, 2007, 1:25am UTC](https://www.ruby-forum.com/t/chaining-validate-method-in-a-plugin-completely-stumped/112850/4 "2007-08-25T01:25:07Z")

</div>

Mike G. 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.

---

<div class="post-metadata">

**Author:** ![random52k](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@random52k](https://www.ruby-forum.com/u/random52k)\
**Post date:** [August 25, 2007, 5:05am UTC](https://www.ruby-forum.com/t/chaining-validate-method-in-a-plugin-completely-stumped/112850/5 "2007-08-25T05:05:23Z")

</div>

Mike G. wrote:

> 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.

---

<div class="post-metadata">

**Author:** ![random52k](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@random52k](https://www.ruby-forum.com/u/random52k)\
**Post date:** [August 25, 2007, 1:50am UTC](https://www.ruby-forum.com/t/chaining-validate-method-in-a-plugin-completely-stumped/112850/6 "2007-08-25T01:50:09Z")

</div>

On 8/24/07, Mark Reginald J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Mike G. 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

---

<div class="post-metadata">

**Author:** ![random52k](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@random52k](https://www.ruby-forum.com/u/random52k)\
**Post date:** [August 29, 2007, 11:32pm UTC](https://www.ruby-forum.com/t/chaining-validate-method-in-a-plugin-completely-stumped/112850/7 "2007-08-29T23:32:34Z")

</div>

On 8/24/07, Mark Reginald J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> validate # Call AR::B validate or UserClass 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
