With my functional tests (on PgSQL) I get strange errors like this
1) Error:
test_create(AufgabeControllerTest):
ActiveRecord::StatementInvalid: ERROR: duplicate key violates unique
constraint "aufgaben_pkey"
Tracking this down, I found that sequences are only reset for some of
the tables I''m using. The reason? Inconsistent singularization.
I won''t go so far as to say that plurals are bad, but their handling in
Rails is blatant violation of the DRY principle.
Fixtures has a method for resetting PostgreSQL sequences
def self.reset_sequences(connection, table_names)
table_names.flatten.each do |table|
table_class = Inflector.classify(table.to_s)
if Object.const_defined?(table_class)
pk = eval("#{table_class}::primary_key")
if pk == ''id''
connection.execute(
"SELECT setval(''#{table.to_s}_id_seq'',
(SELECT MAX(id) FROM
#{table.to_s}), true)",
''Setting Sequence''
)
end
end
end
end
The smelly line in there is
Inflector.classify(table.to_s)
which simply auto-singularizes and camel cases the table name. A thing
that might sort of work for english terms, it doesn''t work for other
languages at all. In most places in Rails it is possible to work around
auto-singularization/-pluralization, e.g. by set_table_name, explicitly
defining :class_name and :foreign_key options. Not in this case.
The problem is not with plurals per se or with Rails doing (trying)
automatic translation between singular and plural forms. The problem is
-- and that''s where DRY enters -- that it is handled inconsistently. If
I tell ActiveRecord once that this class(_name) is related to that
table_name, I want it to remember that and use the information in every
context where mapping from one to the other is required.
Obviously, that is not the case. I can''t remember how many places in
the
Rails codebase I''ve seen where class names and table names are
converted into each other. Unfortunately, not with the help of two
specific methods, which could rely on a mapping table, but by
manipulating the syntactic arcana of the english language.
What to do about this? The only solution I can imagine right now
consists of these pieces
- Funnel each and every conversion between singular and plural as well
as class name and table name through centralized methods.
- Add table-based conversion that gets priority over existing rule-based
conversion.
- Allow explicit registering of entries in this conversion table. In
environment.rb, say.
- When table_names are set on AR classes, remember this in the
conversion table.
Michael
--
Michael Schuerig Life is just as deadly
mailto:michael-q5aiKMLteq4b1SvskN2V4Q@public.gmane.org
As it looks
http://www.schuerig.de/michael/ --Richard Thompson, Sibella