# Redefining before\_validation for an ActiveRecord model

**URL:** <https://www.ruby-forum.com/t/redefining-before-validation-for-an-activerecord-model/127138>\
**Category:** Rails\
**Created:** [January 25, 2008, 11:07am UTC](https://www.ruby-forum.com/t/redefining-before-validation-for-an-activerecord-model/127138 "2008-01-25T11:07:57Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Wim\_Ceulemans](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/65b543/32.png) [@Wim\_Ceulemans](https://www.ruby-forum.com/u/Wim_Ceulemans)\
**Post date:** [January 25, 2008, 11:07am UTC](https://www.ruby-forum.com/t/redefining-before-validation-for-an-activerecord-model/127138/1 "2008-01-25T11:07:57Z")

</div>

Hi

I’m struggling more then a day now to try to write a simple plugin.

Let me explain what the plugin should do.  
Consider a table called categories that looks like:

create\_table :categories do |t|  
t.column :id, :integer  
t.column :categorizable\_type, :string, :null =\> false  
t.column :categorizable\_id, :integer, :null =\> false,  
:references =\> nil  
t.column :category\_name, :integer, :null =\> false  
end

with model:

class Category \< ActiveRecord::Base  
belongs\_to :categorizable, :polymorphic =\> true  
validates\_presence\_of :categorizable\_type, :categorizable\_id  
end

Then for example a product is categorizable, table and model of product  
look like this:

create\_table :products do |t|  
t.column :id, :integer  
t.column :code, :string  
end

class Product \< ActiveRecord::Base  
has\_many :categories, :as =\> :categorizable  
end

So products are categorizable. Now I want to define a model  
product\_categories that contains all categories for products.

The definition of product\_categories is:  
class ProductCategory \< Category  
set\_scope :categorizable\_type, “Product”  
end

Notice the ‘set\_scope’ definition. This is the plugin I am writing  
(called ScopedModel) and the idea is that when a model gets the  
set\_scope definition, automatically the categorizable\_type should be on  
‘Product’ for all manipulations.  
For example:

ProductCategory.find(:all) should result in:

select \* from categories where categorizable\_type=‘Product’

ProductCategory.create!(category\_name =\> ‘some\_name’) should result in a  
record being created where categorizable\_type has value ‘Product’.

So all operations on ProductCategory should result in making sure that  
everything is qualified with 'categorizable\_type = ‘Product’.  
Until now I have been able to make it work for find, but I can’t let it  
work for create, update ,…

My working plugin code until now is:

ActiveRecord::Base.send :include, ScopedModel

module ScopedModel  
def self.included(base)  
base.class\_eval do  
class \<\< self  
alias\_method :orig\_find\_every, :find\_every

```
            def set_scope(attribute,value)
                @model_scope ||= {}
                @model_scope[attribute] = value
            end

            # redefine find
            private
            def find_every(*args)
                @find_option = Hash.new
                @model_scope ||= {}
                @model_scope.each_key do |attribute|
                    value = @model_scope[attribute]
                    @find_option[:conditions] = "#{attribute} =

```

‘#{value}’"  
end  
with\_scope :find =\> (@find\_option) do  
orig\_find\_every(\*args)  
end  
end  
end  
end  
end  
end

(I borrowed the code from the excellent HOWTO, see  
[http://www.railsforum.com/viewtopic.php?id=682](http://www.railsforum.com/viewtopic.php?id=682)

So the find method automatically adds the scope qualification by adding  
it to the find of the class’s singleton class.  
For the create, update, I want to use the ‘before\_validation’ method. If  
I put next in my ProductCategory model:

def before\_validation  
self.categorizable\_type = ‘Product’  
end

Problem is that I should be able to define this before\_validation in the  
plugin in the singleton class for product\_category.  
And I tried everything but nothing works. The code in the plugin should  
be something like:

alias\_method :orig\_before\_validation, :before\_validation  
def before\_validation  
@model\_scope ||= {}  
@model\_scope.each\_key do |attribute|  
self.attribute = @model\_scope[attribute]  
end  
orig\_before\_validation  
end

Problem is that before\_validation is mixed\_in in ActiveRecord::Base and  
also that it should work on an instance and not at class\_level, while my  
definition of set\_scope is at (singleton) class level,

Hope that anyone can shed some light on this problem.

## Thanks and Regards Wim

NEW on aXs GUARD: SSL VPN !! (contact your reseller for more info)

* * *

## aXs GUARD has completed security and anti-virus checks on this e-mail ([http://www.axsguard.com](http://www.axsguard.com))

Able NV: ond.nr 0457.938.087  
RPR Mechelen
