# Acts\_as\_whatever

**URL:** <https://www.ruby-forum.com/t/acts-as-whatever/53182>\
**Category:** Rails\
**Created:** [January 27, 2006, 8:19pm UTC](https://www.ruby-forum.com/t/acts-as-whatever/53182 "2006-01-27T20:19:47Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![samj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/77aa72/32.png) [@samj](https://www.ruby-forum.com/u/samj)\
**Post date:** [January 27, 2006, 8:19pm UTC](https://www.ruby-forum.com/t/acts-as-whatever/53182/1 "2006-01-27T20:19:47Z")

</div>

Hi there,

I love the acts\_as\_\* family that rails uses. I’ve also found I can  
create something similar by dropping the following code into my  
activerecord classes:

class MyClass \< ActiveRecord::Base

class \<\< self  
alias\_method :count\_with\_unapproved, :count  
end

def self.find(\*args)  
options = extract\_options\_from\_args!(args)  
if options[:conditions].nil?  
options[:conditions] = [“status = ‘approved’”]  
end  
args \<\< options  
super(\*args)  
end

def self.count(conditions = nil, joins = nil)  
logger.info conditions.inspect  
if conditions.nil?  
conditions = “status = ‘approved’”  
else  
case conditions  
when String then conditions += " AND status = ‘approved’"  
when Array then conditions[0] +=" AND status = ‘approved’"  
end  
end  
super(conditions, joins)  
end  
end

which lets me get the equivalent functionality of something like  
acts\_as\_approved, where I can easily subdivide my records into approved  
and not approved.

I’d love this to be a mixin, but when I look at the code for, say,  
acts\_as\_paranoid I feel like the ruby novice I am. I’d like to create  
other versions of this, like acts\_as\_private that would allow me to  
divide off other things based on the setting in a private field, but  
again, I don’t feel like I’m ready to create my own mixin from scratch.

I was thinking it would be cool to have mixin called “acts\_as\_whatever”  
that you could use like this:

class MyClass \< ActiveRecord::Base  
acts\_as\_whatever :status =\> ‘approved’  
end

which would do the same as my code above - anybody know if that’s  
practical?

Then I could do things like:

class MyClass \< ActiveRecord::Base  
acts\_as\_whatever :public=\> ‘true’  
end

I guess alternatively I could just extend ActiveRecord::Base and make my  
private or status-oriented classes extend that, or I could try again to  
get my head round mixin creation.

Any thoughts?

CHEERS\> SAM

---

<div class="post-metadata">

**Author:** ![samj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/77aa72/32.png) [@samj](https://www.ruby-forum.com/u/samj)\
**Post date:** [May 1, 2007, 10:49pm UTC](https://www.ruby-forum.com/t/acts-as-whatever/53182/2 "2007-05-01T22:49:16Z")

</div>

Hi,  
I am currently studying the acts\_as\_whatever design because I would like  
to implement something like an “acts\_as\_noteable.” My idea is just to  
be able to have simple text notes for any given model. Of course there  
would be many possible notes. The problem is that I do not want to mess  
with adding new tables. I just want one “whatever” table. The problem  
is that I would have to continually add fields to that one database  
table everytime I make another object to be “noteable.” This is more of  
a database design issue but has some relevance because if I use the  
“acts\_as\_whatever” system or the “acts\_as\_taggable” style code then I  
have to always manually add tables. Isn’t there a simple way to do this  
without adding either tables or fields in the database (once the initial  
db design if found)? To restate, I mean to say that I want to add only  
rows, not tables or columns. I am sort of stuck on this db problem  
(forcing me to study some db theory). I thought the people who designed  
“acts\_as\_whatever” template might have thought about how to avoid adding  
tables or fields.

Thanks for any input!

Philip

---

<div class="post-metadata">

**Author:** ![samj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/77aa72/32.png) [@samj](https://www.ruby-forum.com/u/samj)\
**Post date:** [May 2, 2007, 12:50am UTC](https://www.ruby-forum.com/t/acts-as-whatever/53182/3 "2007-05-02T00:50:58Z")

</div>

> The problem is that I would have to continually add fields to that  
> one database table everytime I make another object to be “noteable.”

Instead of making another database table every time you want to make an  
object “noteable” use polymorphic associations  
([http://wiki.rubyonrails.org/rails/pages/UnderstandingPolymorphicAssociations](http://wiki.rubyonrails.org/rails/pages/UnderstandingPolymorphicAssociations)).  
It’s actually the perfect instance to use them.

note.rb:

class Note \<\< ActiveRecord::Base  
belongs\_to :noteable, :polymorphic =\> true  
end

any\_class\_with\_note.rb:

class AnyClassWithNote \<\< ActiveRecord::Base  
has\_many :note, :as =\> :noteable  
end

another\_class\_with\_note.rb:

class AnotherClassWithNote \<\< ActiveRecord::Base  
has\_many :note, :as =\> :noteable  
end

schema.rb:

create\_table “another\_class\_with\_notes”, :force =\> true do |t|  
…  
end

create\_table “any\_class\_with\_notes”, :force =\> true do |t|  
…  
end

create\_table “notes”, :force =\> true do |t|  
t.column “title”, :string  
t.column “description”, :text  
t.column “user\_id”, :integer  
t.column “created\_at”, :datetime  
t.column “updated\_at”, :datetime  
t.column “noteable\_type”, :string  
t.column “noteable\_id”, :integer  
end

---

<div class="post-metadata">

**Author:** ![samj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/77aa72/32.png) [@samj](https://www.ruby-forum.com/u/samj)\
**Post date:** [May 2, 2007, 5:02am UTC](https://www.ruby-forum.com/t/acts-as-whatever/53182/4 "2007-05-02T05:02:28Z")

</div>

Thanks for the extra information. It is helpful. My problem was that I  
was trying first to think of this “acts\_as\_whatever” concept within the  
relational modelling “sphere of influence”. Once fully understood at  
the db level, then I wanted to understand it from the ORM level.  
However, I wanted to have a db design which did not “store” anything  
about the tables themselves. In other words I tried to design it with  
E-R diagrams using only the basic techniques. Specifically I wanted to  
avoid a table which was itself a list of tables which were “noteable”.  
Interesting, it was not easy to keep the E-R conceptual model “flat”…  
It appears that you must start storing “object meta data” somewhere  
before you can implement “acts\_as\_whatever” on the tables. I know I am  
belaboring the point. However, this is very rich fodder for the student  
of the two design spheres (ORM and DB). Specifically, I hoped it would  
shed some light on the relationship between “object realm” and “DB  
realm”.

Thanks for the input!

Philip

Suggester wrote:

> > The problem is that I would have to continually add fields to that  
> > one database table everytime I make another object to be “noteable.”
> 
> Instead of making another database table every time you want to make an  
> object “noteable” use polymorphic associations  
> ([http://wiki.rubyonrails.org/rails/pages/UnderstandingPolymorphicAssociations](http://wiki.rubyonrails.org/rails/pages/UnderstandingPolymorphicAssociations)).  
> It’s actually the perfect instance to use them.
> 
> note.rb:
> 
> class Note \<\< ActiveRecord::Base  
> belongs\_to :noteable, :polymorphic =\> true  
> end
> 
> any\_class\_with\_note.rb:
> 
> class AnyClassWithNote \<\< ActiveRecord::Base  
> has\_many :note, :as =\> :noteable  
> end
> 
> another\_class\_with\_note.rb:
> 
> class AnotherClassWithNote \<\< ActiveRecord::Base  
> has\_many :note, :as =\> :noteable  
> end
> 
> schema.rb:
> 
> create\_table “another\_class\_with\_notes”, :force =\> true do |t|  
> …  
> end
> 
> create\_table “any\_class\_with\_notes”, :force =\> true do |t|  
> …  
> end
> 
> create\_table “notes”, :force =\> true do |t|  
> t.column “title”, :string  
> t.column “description”, :text  
> t.column “user\_id”, :integer  
> t.column “created\_at”, :datetime  
> t.column “updated\_at”, :datetime  
> t.column “noteable\_type”, :string  
> t.column “noteable\_id”, :integer  
> end

---

<div class="post-metadata">

**Author:** ![samj](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/77aa72/32.png) [@samj](https://www.ruby-forum.com/u/samj)\
**Post date:** [May 2, 2007, 4:15pm UTC](https://www.ruby-forum.com/t/acts-as-whatever/53182/5 "2007-05-02T16:15:26Z")

</div>

I think  
acts\_as\_commentable[http://www.juixe.com/techknow/index.php/2006/06/18/acts-as-commentable-plugin/](http://www.juixe.com/techknow/index.php/2006/06/18/acts-as-commentable-plugin/)plugin  
will do the notes for you.
