Hello all. I am new both to Ruby and ROR. I am hoping that ROR will be suited to working with a very large (hundreds of tables) SQL server database. Needless to say this database does not obey any of the naming rules that active record likes. So far I have found out how to manually specify the table name and the name of the primary key but I haven''t figured out how to give "nice" names to the some of the fields in my table. For example if I have a field called FIELD5 I want to refer to it as CustomerName (don''t laugh it could happen to you too!). Is there a way to give active record a hash of table names and "nice names" such that it uses the nice names in the object to update the table?
On Wed, 30 Mar 2005 14:41:10 -0700, tim <tim-0svUrQI80TQAvxtiuMwx3w@public.gmane.org> wrote:> Hello all. > > I am new both to Ruby and ROR. I am hoping that ROR will be suited to > working with a very large (hundreds of tables) SQL server database. > Needless to say this database does not obey any of the naming rules that > active record likes. So far I have found out how to manually specify the > table name and the name of the primary key but I haven''t figured out how > to give "nice" names to the some of the fields in my table. For example > if I have a field called FIELD5 I want to refer to it as CustomerName > (don''t laugh it could happen to you too!). Is there a way to give active > record a hash of table names and "nice names" such that it uses the nice > names in the object to update the table?I think you''ll find this an uphill battle. RoR was designed for new applications, not for legacy apps. It trades off some flexibility for ease of use and development spee.d Two options that I see: 1) Specify the columns manually: def customer_name read_attribute ''field5'' end def customer_name=(s) write_attribute ''field5'', s end Using Ruby''s eval methods, I''m sure you could write something that would generate those method stubs given a list of fieldnames and table names. I don''t believe AR has this feature currently, however. 2) Create a view in your database that gives you nice column names. -- rick http://techno-weenie.net
Would I muck things up too bad if I overrode the missing_method on my object? I was thinking I would write a script that reads the database and then generates the classes in one fell swoop. Rick Olson wrote:>On Wed, 30 Mar 2005 14:41:10 -0700, tim <tim-0svUrQI80TQAvxtiuMwx3w@public.gmane.org> wrote: > > >>Hello all. >> >>I am new both to Ruby and ROR. I am hoping that ROR will be suited to >>working with a very large (hundreds of tables) SQL server database. >>Needless to say this database does not obey any of the naming rules that >>active record likes. So far I have found out how to manually specify the >>table name and the name of the primary key but I haven''t figured out how >>to give "nice" names to the some of the fields in my table. For example >>if I have a field called FIELD5 I want to refer to it as CustomerName >>(don''t laugh it could happen to you too!). Is there a way to give active >>record a hash of table names and "nice names" such that it uses the nice >>names in the object to update the table? >> >> > >I think you''ll find this an uphill battle. RoR was designed for new >applications, not for legacy apps. It trades off some flexibility for >ease of use and development spee.d > >Two options that I see: > >1) Specify the columns manually: > >def customer_name > read_attribute ''field5'' >end > >def customer_name=(s) > write_attribute ''field5'', s >end > >Using Ruby''s eval methods, I''m sure you could write something that >would generate those method stubs given a list of fieldnames and table >names. I don''t believe AR has this feature currently, however. > >2) Create a view in your database that gives you nice column names. > > > >
I read up a little bit on ruby and on the activerecord and I believe I have come up with an approach to solving the field name mapping problem by making a small modification to activercord::base. As a bonus this apporach might also quell the "I can''t tell just by looking what the fields are" argument that has been made lately. I think my patch might allow one to do this. class Account < ActiveRecord::Base @@field_name_map = {''account_balance'' => ''acctbal'', ''account_name'' => ''acctname''} end Once again I am new and this could be a horrible idea or might not work at all. I would appreciate any further insight you guys may have into this matter. All I did was to make a minor change to method_missing and defined a class level hash here is the patch. 247a248,251> > # Field Name map to translate ugly field names to nice method names > # No accessor is defined for now. > @@field_name_map = {}774a779,784> elsif (''='' == method_name[-1,1]) and @@FieldNameMap.has_key? method_name.chop > # It''s a setter > write_attribute(@@FieldNameMap[method_name.chop], arguments[0]) > elsif @@FieldNameMap.has_key? method_name > #it''s a getter > read_attribute(@@FieldNameMap[method_name])On Mar 30, 2005 2:49 PM, Rick Olson <technoweenie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Wed, 30 Mar 2005 14:41:10 -0700, tim <tim-0svUrQI80TQAvxtiuMwx3w@public.gmane.org> wrote: > > Hello all. > > > > I am new both to Ruby and ROR. I am hoping that ROR will be suited to > > working with a very large (hundreds of tables) SQL server database. > > Needless to say this database does not obey any of the naming rules that > > active record likes. So far I have found out how to manually specify the > > table name and the name of the primary key but I haven''t figured out how > > to give "nice" names to the some of the fields in my table. For example > > if I have a field called FIELD5 I want to refer to it as CustomerName > > (don''t laugh it could happen to you too!). Is there a way to give active > > record a hash of table names and "nice names" such that it uses the nice > > names in the object to update the table? > > I think you''ll find this an uphill battle. RoR was designed for new > applications, not for legacy apps. It trades off some flexibility for > ease of use and development spee.d > > Two options that I see: > > 1) Specify the columns manually: > > def customer_name > read_attribute ''field5'' > end > > def customer_name=(s) > write_attribute ''field5'', s > end > > Using Ruby''s eval methods, I''m sure you could write something that > would generate those method stubs given a list of fieldnames and table > names. I don''t believe AR has this feature currently, however. > > 2) Create a view in your database that gives you nice column names. > > -- > rick > http://techno-weenie.net > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
The Rails philosophy is to keep things DRY. This is unnecessarily repeating one''s self. Asking DHH to make Rails more verbose is like asking Steve Jobs to sell Apple to Microsoft, it simply will never happen. -Lucas http://www.rufy.com/ On Apr 1, 2005, at 11:50 PM, Tim Uckun wrote:> I read up a little bit on ruby and on the activerecord and I believe I > have come up with an approach to solving the field name mapping > problem by making a small modification to activercord::base. As a > bonus this apporach might also quell the "I can''t tell just by looking > what the fields are" argument that has been made lately. I think my > patch might allow one to do this. > > class Account < ActiveRecord::Base > @@field_name_map = {''account_balance'' => ''acctbal'', ''account_name'' > => ''acctname''} > end > > Once again I am new and this could be a horrible idea or might not > work at all. I would appreciate any further insight you guys may have > into this matter. All I did was to make a minor change to > method_missing and defined a class level hash here is the patch. > > 247a248,251 >> >> # Field Name map to translate ugly field names to nice method >> names >> # No accessor is defined for now. >> @@field_name_map = {} > 774a779,784 >> elsif (''='' == method_name[-1,1]) and >> @@FieldNameMap.has_key? method_name.chop >> # It''s a setter >> write_attribute(@@FieldNameMap[method_name.chop], >> arguments[0]) >> elsif @@FieldNameMap.has_key? method_name >> #it''s a getter >> read_attribute(@@FieldNameMap[method_name]) > > > > > > On Mar 30, 2005 2:49 PM, Rick Olson <technoweenie-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: >> On Wed, 30 Mar 2005 14:41:10 -0700, tim <tim-0svUrQI80TQAvxtiuMwx3w@public.gmane.org> wrote: >>> Hello all. >>> >>> I am new both to Ruby and ROR. I am hoping that ROR will be suited to >>> working with a very large (hundreds of tables) SQL server database. >>> Needless to say this database does not obey any of the naming rules >>> that >>> active record likes. So far I have found out how to manually specify >>> the >>> table name and the name of the primary key but I haven''t figured out >>> how >>> to give "nice" names to the some of the fields in my table. For >>> example >>> if I have a field called FIELD5 I want to refer to it as CustomerName >>> (don''t laugh it could happen to you too!). Is there a way to give >>> active >>> record a hash of table names and "nice names" such that it uses the >>> nice >>> names in the object to update the table? >> >> I think you''ll find this an uphill battle. RoR was designed for new >> applications, not for legacy apps. It trades off some flexibility for >> ease of use and development spee.d >> >> Two options that I see: >> >> 1) Specify the columns manually: >> >> def customer_name >> read_attribute ''field5'' >> end >> >> def customer_name=(s) >> write_attribute ''field5'', s >> end >> >> Using Ruby''s eval methods, I''m sure you could write something that >> would generate those method stubs given a list of fieldnames and table >> names. I don''t believe AR has this feature currently, however. >> >> 2) Create a view in your database that gives you nice column names. >> >> -- >> rick >> http://techno-weenie.net >> _______________________________________________ >> Rails mailing list >> Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org >> http://lists.rubyonrails.org/mailman/listinfo/rails >> > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails
Hi Rick,> I read up a little bit on ruby and on the activerecord and I > believe I have come up with an approach to solving the field > name mapping problem by making a small modification to > activercord::base. As a bonus this apporach might also quell > the "I can''t tell just by looking what the fields are" > argument that has been made lately. I think my patch might > allow one to do this. > > class Account < ActiveRecord::Base > @@field_name_map = {''account_balance'' => ''acctbal'', ''account_name'' > => ''acctname''} > endI''ve been working on some ideas along a similar vein, only I''ve delegated the method for transforming fieldnames/tablenames/classnames to/from human-names to an external class (well actually a set of classes, all descended from AbstractNamingConvention). So, one can think of a new way of naming things (like "lets keep a list of fieldname mappings in a table"), create a new class that descends from AbstractNamingConvention that implements this way of naming things, and then point AR at it, like so: ActiveRecord::Base.field_naming_convention = UseFieldNameTable ActiveRecord::Base.attribute_naming_convention = UseAttributeTable My approach is slightly more complicated than yours, because I need two naming conventions to get from field names to attribute names: attribute_name attribute_naming_convention.encode(field_naming_convention.decode(field_name )) One upshot of this is that the human-names need not be restricted to English. The Attribute table could contain mappings between attribute-names (as used in code) and human-names in multiple languages, so one would then simply write: ActiveRecord::Base.field_naming_convention = UseFieldNameTable ActiveRecord::Base.attribute_naming_convention UseMultilanguageAttributeTable(user_language) I have this working for table_names/class_names now, but I''m not sure that patching Rails is necessarily the way to go. I like the lean and mean design of AR as it stands and not everyone needs these features. AR (by virtual of being written in Ruby) lends itself nicely to being extended via mix-in modules and plain old class inheritance. The framework I''m working on adds some extra things (like class table inheritance) by wrapping AR and not modifying any AR code at all. Adelle.
Tim Uckun wrote:> I read up a little bit on ruby and on the activerecord and I believe I > have come up with an approach to solving the field name mapping > problem by making a small modification to activercord::base. As a > bonus this apporach might also quell the "I can''t tell just by looking > what the fields are" argument that has been made lately. I think my > patch might allow one to do this. >[...]> > Once again I am new and this could be a horrible idea or might not > work at all. I would appreciate any further insight you guys may have > into this matter. All I did was to make a minor change to > method_missing and defined a class level hash here is the patch.Tim, thanks for digging in and writing code. The contentious threads here should take a cue: more walk, less talk ;) Please post your contribution to http://dev.rubyonrails.com Whether and to what degree Active Record should act as a "data mapper" rather than as a direct view on the table is a delicate balance; hence the debate. It seems that writing new database views for a legacy schema is more painful (and less likely to be approved) than simply writing a column mapping. However, an optional column mapping may become de-facto or, worse, required. Best, jeremy
Well that was me Tim and not Rick. Anyway I just did the simplest thing that could possibly work for my particular problem. I had originally done it in another class which inherited from AR but thought it might be best to push down into the AR itself. It''s only a few lines of code. I have no idea how my patch will effect the attributes. I was kind of hoping it would happen magically :). Your approach seems much more comprehensive but I have no knowledge of AbstractNamingConvention. One of the ideas I had was to generate all the methods on class instantiation using the field name map. If this approach does not work then I will probably try doing that. Finally if I had to choose I would choose against storing all the name mappings in the database. That means going to two places to modify the app, I would rather have it right inside my class so I can grep it and version it. Also it would mean an extra trip to the database on every hit. On Apr 2, 2005 1:32 AM, Adelle Hartley <adelle-JNHwCBCQwwtx3z9c7Zyw2w@public.gmane.org> wrote:> Hi Rick, > > > I read up a little bit on ruby and on the activerecord and I > > believe I have come up with an approach to solving the field > > name mapping problem by making a small modification to > > activercord::base. As a bonus this apporach might also quell > > the "I can''t tell just by looking what the fields are" > > argument that has been made lately. I think my patch might > > allow one to do this. > > > > class Account < ActiveRecord::Base > > @@field_name_map = {''account_balance'' => ''acctbal'', ''account_name'' > > => ''acctname''} > > end > > I''ve been working on some ideas along a similar vein, only I''ve delegated > the method for transforming fieldnames/tablenames/classnames to/from > human-names to an external class (well actually a set of classes, all > descended from AbstractNamingConvention). > > So, one can think of a new way of naming things (like "lets keep a list of > fieldname mappings in a table"), create a new class that descends from > AbstractNamingConvention that implements this way of naming things, and then > point AR at it, like so: > > ActiveRecord::Base.field_naming_convention = UseFieldNameTable > ActiveRecord::Base.attribute_naming_convention = UseAttributeTable > > My approach is slightly more complicated than yours, because I need two > naming conventions to get from field names to attribute names: > > attribute_name > attribute_naming_convention.encode(field_naming_convention.decode(field_name > )) > > One upshot of this is that the human-names need not be restricted to > English. The Attribute table could contain mappings between attribute-names > (as used in code) and human-names in multiple languages, so one would then > simply write: > > ActiveRecord::Base.field_naming_convention = UseFieldNameTable > ActiveRecord::Base.attribute_naming_convention > UseMultilanguageAttributeTable(user_language) > > I have this working for table_names/class_names now, but I''m not sure that > patching Rails is necessarily the way to go. I like the lean and mean > design of AR as it stands and not everyone needs these features. > > AR (by virtual of being written in Ruby) lends itself nicely to being > extended via mix-in modules and plain old class inheritance. > > The framework I''m working on adds some extra things (like class table > inheritance) by wrapping AR and not modifying any AR code at all. > > Adelle. > >
Tim Uckun wrote:>I read up a little bit on ruby and on the activerecord and I believe I >have come up with an approach to solving the field name mapping >problem by making a small modification to activercord::base. As a >bonus this apporach might also quell the "I can''t tell just by looking > what the fields are" argument that has been made lately. I think my >patch might allow one to do this. > >class Account < ActiveRecord::Base > @@field_name_map = {''account_balance'' => ''acctbal'', ''account_name'' >=> ''acctname''} > end > >Why not just, 1. Use ''account_balance'' in the database in the first place. 2. Use def class_name ... alias account_balance acctbal alias account_balance= acctbal alias account_name acctname alias account_name= acctname... end But I think #1 is the better advice here. - Adam
1. Use ''account_balance'' in the database in the first place. Too late, it''s a legacy database. "alias account_balance acctbal alias account_balance= acctbal=" I just thought that it would be easier the way I did it. The way I did it the base class handles all the account mapping. Although now that I have read a bit more about class variables the way I did it might not work. In the end if I am going to use ROR it looks like I am going to have to write some sort of a code generator anyway. I suppose it would be faster to use the alias method then the missing_method implementation. Thanks for the tip. On Apr 6, 2005 4:29 PM, Adam M. <gnuman1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Tim Uckun wrote: > > >I read up a little bit on ruby and on the activerecord and I believe I > >have come up with an approach to solving the field name mapping > >problem by making a small modification to activercord::base. As a > >bonus this apporach might also quell the "I can''t tell just by looking > > what the fields are" argument that has been made lately. I think my > >patch might allow one to do this. > > > >class Account < ActiveRecord::Base > > @@field_name_map = {''account_balance'' => ''acctbal'', ''account_name'' > >=> ''acctname''} > > end > > > > > > Why not just, > > 1. Use ''account_balance'' in the database in the first place. > 2. Use > > def class_name > ... > alias account_balance acctbal > alias account_balance= acctbal> alias account_name acctname > alias account_name= acctname> ... > end > > But I think #1 is the better advice here. > > - Adam > >