# Redefining before\_validation for an ActiveRecord model

**URL:** <https://discuss.rubyonrails.org/t/redefining-before-validation-for-an-activerecord-model/23833>\
**Category:** rubyonrails-talk\
**Created:** [January 25, 2008, 10:07am UTC](https://discuss.rubyonrails.org/t/redefining-before-validation-for-an-activerecord-model/23833 "2008-01-25T10:07:11Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Wim\_Ceulemans](https://avatars.discourse-cdn.com/v4/letter/w/65b543/32.png) [@Wim\_Ceulemans](https://discuss.rubyonrails.org/u/Wim_Ceulemans)\
**Post date:** [January 25, 2008, 10:07am UTC](https://discuss.rubyonrails.org/t/redefining-before-validation-for-an-activerecord-model/23833/1 "2008-01-25T10:07:11Z")

</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| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.column :id, :integer &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.column :categorizable\_type, :string, :null =\> false &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.column :categorizable\_id, :integer, :null =\> false, :references =\> nil &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.column :id, :integer &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.column :code, :string end

class Product \< ActiveRecord::Base &nbsp;&nbsp;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 &nbsp;&nbsp;&nbsp;&nbsp;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 &nbsp;&nbsp;&nbsp;&nbsp;def self.included(base) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;base.class\_eval do &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class \<\< self &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alias\_method :orig\_find\_every, :find\_every

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def set\_scope(attribute,value) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@model\_scope ||= {} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@model\_scope[attribute] = value &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# redefine find &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def find\_every(\*args) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@find\_option = Hash.new &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@model\_scope ||= {} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@model\_scope.each\_key do |attribute| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = @model\_scope[attribute] &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@find\_option[:conditions] = "#{attribute} = '#{value}'" &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with\_scope :find =\> (@find\_option) do &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;orig\_find\_every(\*args) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end &nbsp;&nbsp;&nbsp;&nbsp;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 &nbsp;&nbsp;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 &nbsp;&nbsp;@model\_scope ||= {} &nbsp;&nbsp;@model\_scope.each\_key do |attribute| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.attribute = @model\_scope[attribute] &nbsp;&nbsp;end &nbsp;&nbsp;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
