I started writing this before I discovered that I can do this: ActiveRecord::Base::pluralize_table_names = false That fixes my immediate problem, but nevertheless... I propose a new class, that I will call abstract_naming_convention. Subclasses of this class would implement a conversion between "human" names and "code" names based on a specific naming convention. ActiveRecord would need to know about this class, but its potential uses extend beyond ActiveRecord: class abstract_naming_convention # take a "human" name and return a "code" name. def encode(human_name) end # take a "code" name and return a "human" name. def decode(code_name) end end A typical "real life" database makes use of multiple naming conventions. eg, the naming of tables, the naming of fields, the naming of indexes, etc. So, ActiveRecord::Base could have a class attribute for each naming convention used. Those of us from the "if it ain''t broke, don''t fix it" school of thought may need a little convincing, since ActiveRecord::Base already has the following naming convention related class attributes: primary_key_prefix_type table_name_prefix table_name_suffix pluralize_table_names And it wouldn''t be too hard to add a table_name_infix, to indicate whether a table_name should contain an underscore character between words, etc. But abstracting the idea of a naming convention out of Active record opens up some possibilities. Dealing with exceptions would become a breeze - just subclass a standard naming convention: class special_naming_convention < plural_naming_convention def encode(human_name) # deal with an exceptional case if human_name == ''person'' ''people'' else super end end def decode(code_name) # deal with an exceptional case if code_name == ''people'' ''person'' else super end end end Completely arbitrary table names would also be possible, by creating a naming_convention that looked up the class name in a table to determine the table name. (I have a project where that would be useful, because the "human" names are too long to represent directly as table names in the underlying database). Does anyone here, who has a better knowledge of the standard libraries, know whether there is already an existing standard class that implements this pattern? Adelle.
Alexey Verkhovsky
2005-Jan-26 12:22 UTC
Re: abstract_naming_convention (proposal for new class)
Adelle Hartley wrote:>I propose a new class, that I will call abstract_naming_convention. > >I have some experience of explaining to ActiveRecord a naming convention for tables, primary and foreign keys of a legacy database. Although it''s not difficult to do with current AR, it required changing some behaviors of ActiveRecord::Base that were not part of a published interface. So, I second this proposal. But let''s go one step further and call it AbstractModel, a class that would (similar to ApplicationController) contain behaviors common for all model classes, _including_ the DB naming convention. In both Rails applications I wrote to date some such construct was needed. -- Best regards, Alexey Verkhovsky Ruby Forum: http://ruby-forum.org (moderator) RForum: http://rforum.andreas-s.net (co-author) Instiki: http://instiki.org (maintainer)
Adelle Hartley
2005-Jan-26 12:39 UTC
RE: abstract_naming_convention (proposal for new class)
Alexey Verkhovsky wrote:> But let''s go one step further and call it AbstractModel, a > class that would (similar to ApplicationController) contain > behaviors common for all model classes, _including_ the DB > naming convention. In both Rails applications I wrote to date > some such construct was needed.A model contains multiple naming conventions, because different naming conventions can be used for naming tables vs naming indexes vs naming classes vs naming stored procedures vs naming other objects. So I see abstract_naming_convention as a more basic/fundamental building block than AbstractModel - although AbstractModel sounds like a good idea. I haven''t played with ApplicationController yet, but I think I understand your analogy. The only requirement for a naming_convention implementation would be that it is reversible. ie: NamingConvention::decode(NamingConvention::encode(x)) == x I envisage that to get from a table name to a class name would require two naming_convention implementations. eg: class_name ClassNamingConvention::encode(TableNamingConvention::decode(table_name)) I had previously thought of (and discarded) the idea of a class that would do the translation from table name to class name in a single step. Such a class would be faster, but breaking it into two classes provides a lot more flexibility. Adelle.