Consider this.. A shopping cart application where each merchant has their own table for storing product information. 90% of the time the tables schema''s are the same, but some merchants have added extra columns to their table. The table naming scheme is "[merchant_identifier]_products". There is a single web gui used for all merchants. The merchant identifier is available on every page request. Can a model be created that dynamically sets the table being used to the naming scheme above? Or do I need a new model for each table? And if I do need a new model, I''m thinking that I can still use just one controller to access the different models, assuming that the models all have the same attributes (columns). If I know the merchant identifier, then I also know the model name to use. What I don''t is how to call methods on the model when all I have is a variable holding the model name. For example in perl it would be something like this: my $func = ''test''; &$func; sub test { print "Function test\n"; } Which prints "Function test". I''m completely new to ruby and rails, so if this is pretty basic stuff forgive me. Chris
Deirdre Saoirse Moen
2005-Aug-09 21:00 UTC
Re: single model for multiple tables of same structure
On Tue, 9 Aug 2005, snacktime wrote:> A shopping cart application where each merchant has their own table for > storing product information. 90% of the time the tables schema''s are > the same, but some merchants have added extra columns to their table. > The table naming scheme is "[merchant_identifier]_products".Another way of doing this is to add a key/value table keyed on the product ID for some merchants. That will solve the "extra fields" problem without needing a different schema for each. e.g. something like: create table Product_keys ( product_id int not null, merchant_id int not null, pk_key varchar not null, pk_value varchar(40) not null, primary key (product_id, merchant_id, pk_key) );> And if I do need a new model, I''m thinking that I can still use just one > controller to access the different models, assuming that the models all > have the same attributes (columns). If I know the merchant identifier, > then I also know the model name to use. What I don''t is how to call > methods on the model when all I have is a variable holding the model > name. For example in perl it would be something like this:Sounds way more complicated than my method (and more prone to error in keeping versions synced). -- _Deirdre web / blog: http://deirdre.net/ yarn: http://fuzzyorange.com cat''s blog: http://fuzzyorange.com/vsd/ "Memes are a hoax! Pass it on!"
On 8/9/05, Deirdre Saoirse Moen <deirdre-mzk6fgDMp2XR7s880joybQ@public.gmane.org> wrote:> On Tue, 9 Aug 2005, snacktime wrote: > > > A shopping cart application where each merchant has their own table for > > storing product information. 90% of the time the tables schema''s are > > the same, but some merchants have added extra columns to their table. > > The table naming scheme is "[merchant_identifier]_products". > > Another way of doing this is to add a key/value table keyed on the product > ID for some merchants. That will solve the "extra fields" problem without > needing a different schema for each. > > e.g. something like: > > create table Product_keys ( > product_id int not null, > merchant_id int not null, > pk_key varchar not null, > pk_value varchar(40) not null, > primary key (product_id, merchant_id, pk_key) > ); > > > And if I do need a new model, I''m thinking that I can still use just one > > controller to access the different models, assuming that the models all > > have the same attributes (columns). If I know the merchant identifier, > > then I also know the model name to use. What I don''t is how to call > > methods on the model when all I have is a variable holding the model > > name. For example in perl it would be something like this: > > Sounds way more complicated than my method (and more prone to error in > keeping versions synced).I agree, but this is an existing system with a large userbase. We also use postgresql schema''s in some cases for slightly different reasons (sensitive data that requires extra separation). In that case the table names are the same but the schema name is the merchant identifier. A solution that worked for my first example would probably work for this one also. Chris
snacktime wrote:>Consider this.. > >A shopping cart application where each merchant has their own table >for storing product information. 90% of the time the tables schema''s >are the same, but some merchants have added extra columns to their >table. The table naming scheme is "[merchant_identifier]_products". > >There is a single web gui used for all merchants. The merchant >identifier is available on every page request. Can a model be created >that dynamically sets the table being used to the naming scheme above? > Or do I need a new model for each table? > > >class MyBase < ActiveRecord::Base @@mi = '''' def self.mi=(mi) @@mi = mi end def self.mi @mi end def self.set_table_name(table_name) super(false) { "#{self.schema}.#{table_name}"} end end class MyClass < MyBase set_table_name ''table_name'' end and in the controller call MyClass.mi = ''merchant_id'' I do this in my app to rename tables (for another reason) and it works. So if what I cobbled together doesn''t work for you, mail me directly.
On 8/9/05, Steve Downey <sldowney-TVLZxgkOlNX2fBVCVOL8/A@public.gmane.org> wrote:> snacktime wrote: > > >Consider this.. > > > >A shopping cart application where each merchant has their own table > >for storing product information. 90% of the time the tables schema''s > >are the same, but some merchants have added extra columns to their > >table. The table naming scheme is "[merchant_identifier]_products". > > > >There is a single web gui used for all merchants. The merchant > >identifier is available on every page request. Can a model be created > >that dynamically sets the table being used to the naming scheme above? > > Or do I need a new model for each table? > > > > > > > > class MyBase < ActiveRecord::Base > @@mi = '''' > > def self.mi=(mi) > @@mi = mi > end > > def self.mi > @mi > end > > def self.set_table_name(table_name) > super(false) { "#{self.schema}.#{table_name}"} > end > end > > class MyClass < MyBase > set_table_name ''table_name'' > end > > and in the controller call MyClass.mi = ''merchant_id'' > > I do this in my app to rename tables (for another reason) and it works. > So if what I cobbled together doesn''t work for you, mail me directly.Great that''s just what I was looking for. Thank you. Chris