Forum: Ruby on Rails acts_as_whatever

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Sam J. (Guest)
on 2006-01-27 21:19
(Received via mailing list)
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
Philip D. (Guest)
on 2007-05-02 00:49
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
Suggester (Guest)
on 2007-05-02 02:50
> 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/Understand...).
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
Philip D. (Guest)
on 2007-05-02 07:02
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/Understand...).
> 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
Ivor P. (Guest)
on 2007-05-02 18:15
(Received via mailing list)
I think
acts_as_commentable<http://www.juixe.com/techknow/index.php/2006/06/18...
will do the notes for you.
This topic is locked and can not be replied to.