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