Here''s the code I''m stuck with...
class Hidable < ActiveRecord::Base
def find_all_visible
find(:all, :conditions => ''hidden = false'')
end
end
class Category < Hidable
end
class Product < Hidable
end
Now it appears that ActiveRecord wants this to be a case of
SingleTableInheritance (STI) as I''m inheriting from my Hidable class.
Unfortunately I don''t have a hidables table so everything comes
crashing
down.
Looking in the Agile book, I note that STI is not recommended for
abstract concepts that don''t overlap readily (Product is not a Category
in my example).
The problem is that the proposed solution of creating a meta-class (and
associated table) doesn''t seem to be what I want either. Basically I
jsut want two totally separate ''things'' to share one
particular property
(hidden [Y/N]?) and to do it in the cleanest way.
I can see two ways out:
1 - don''t be DRY and stick the same class method in both classes,
removing the Hidable superclass
2 - try to create a meta-class as a database table, that both Product
and Category have a relationship with (has_one presumably)
I don''t like either choice, can someone provide me with a clue(stick)
here?
Kev
El Miércoles 26 Octubre 2005 09:01, Kev Jackson escribió:> Here''s the code I''m stuck with... > > class Hidable < ActiveRecord::Base > def find_all_visible > find(:all, :conditions => ''hidden = false'') > end > end > > class Category < Hidable > > end > > class Product < Hidable > > end > > Now it appears that ActiveRecord wants this to be a case of > SingleTableInheritance (STI) as I''m inheriting from my Hidable class. > Unfortunately I don''t have a hidables table so everything comes crashing > down. > > Looking in the Agile book, I note that STI is not recommended for > abstract concepts that don''t overlap readily (Product is not a Category > in my example). > > The problem is that the proposed solution of creating a meta-class (and > associated table) doesn''t seem to be what I want either. Basically I > jsut want two totally separate ''things'' to share one particular property > (hidden [Y/N]?) and to do it in the cleanest way. > > I can see two ways out: > > 1 - don''t be DRY and stick the same class method in both classes, > removing the Hidable superclass > 2 - try to create a meta-class as a database table, that both Product > and Category have a relationship with (has_one presumably)What about using mixins? You could write a module called Hidable and mix-in into your hidable classes. The trick is that when you mix-in a module into a class only the instance methods are mixed-in. But, AFAIK, you have two approaches: 1) redefine append features method and do a "normal" include: module Hidable def self.append_features(some_class) def some_class.find_all_visible find(:all, :conditions => ''hidden = false'') end super # Don''t forget call super! end end And, into your class, do "include Hidable". It gives you a class method find_all_visible. 2) write a method in the "simple" way and ''extend'' your class: module Hidable def find_all_visible find(:all, :conditions => ''hidden = false'') end end And into your class do "extend Hidable". Ok, maybe there''s a simpler way, so any suggestion/correction/discussion is welcomed. Good luck! -- Imobach González Sosa imobachgs-gShqw608wn4@public.gmane.org osoh-tVMmVOZxw5Bg9hUCZPvPmw@public.gmane.org
On 26/10/2005, at 6:01 PM, Kev Jackson wrote:> Here''s the code I''m stuck with... > > class Hidable < ActiveRecord::Base > def find_all_visible > find(:all, :conditions => ''hidden = false'') > end > end > > class Category < Hidable > > end > > class Product < Hidable > > end > > Now it appears that ActiveRecord wants this to be a case of > SingleTableInheritance (STI) as I''m inheriting from my Hidable > class. Unfortunately I don''t have a hidables table so everything > comes crashing down.Go and read about the ActiveRecord::Acts module. You could create you own acts_as_hidable: require ''active_support'' require ''active_record'' module ActiveRecord module Acts #:nodoc: module Hidable #:nodoc: def self.append_features(base) super base.extend(ClassMethods) end # Adds a find_all_visible method which finds all records where hidden == false module ClassMethods def acts_as_hidable class_eval do extend ActiveRecord::Acts::Hidable::SingletonMethods end end end module SingletonMethods def find_all_visible find(:all, :conditions => ''hidden = false'') end end end end end then you just end up with: class Product < ActiveRecord::Base acts_as_hidable end -- tim lucas
Tim Lucas wrote:> On 26/10/2005, at 6:01 PM, Kev Jackson wrote: > >> Here''s the code I''m stuck with... >> >> class Hidable < ActiveRecord::Base >> def find_all_visible >> find(:all, :conditions => ''hidden = false'') >> end >> end >> >> class Category < Hidable >> >> end >> >> class Product < Hidable >> >> end >> >> Now it appears that ActiveRecord wants this to be a case of >> SingleTableInheritance (STI) as I''m inheriting from my Hidable >> class. Unfortunately I don''t have a hidables table so everything >> comes crashing down. > > > Go and read about the ActiveRecord::Acts module. > > You could create you own acts_as_hidable: > > require ''active_support'' > require ''active_record'' > > module ActiveRecord > module Acts #:nodoc: > module Hidable #:nodoc: > > def self.append_features(base) > super > base.extend(ClassMethods) > end > > # Adds a find_all_visible method which finds all records where > hidden == false > module ClassMethods > def acts_as_hidable > class_eval do > extend ActiveRecord::Acts::Hidable::SingletonMethods > end > end > end > > module SingletonMethods > def find_all_visible > find(:all, :conditions => ''hidden = false'') > end > end > > end > end > end > > then you just end up with: > > class Product < ActiveRecord::Base > acts_as_hidable > endThanks, this is exactly what I was looking for Kev