On Thursday 14 June 2007, Hugh S. wrote:
pp177-8, second edition.
So, I’m assuming that given Testing is standard practice, in
Databases normalization is standard practice ( == DRY), then there
must be some intention about how one is meant to do this, with the
supplied facilities. This list would seem to be the place to find
that out.
Normalization is fine, but let’s say that there is a certain disregards
in certain circles of the Rails community for enforcing constraints in
the database.
That said, what I’m doing is this. I’m using various of the plugins from
http://www.redhillonrails.org/
to be able to specify FK constraints in migrations and have them show
in schema.rb. Particularly important is the ability to mark FK
constraints as “deferrable”. Also, I’ve patched
Fixtures#create_fixtures to issue
SET CONSTRAINTS ALL DEFERRED
inside the transaction that loads the fixtures (see below). “Deferrable”
constraints can be “deferred”, which means that they are only checked
when the enclosing transaction is about to be committed. This way, it
is possible to load fixture files in any order, even if there are
circular dependencies among tables. I have only tried this in
PostgreSQL, where it works like a charm.
Michael
Put somewhere in RAILS_ROOT/lib and load at startup
require ‘active_record/fixtures’
Fixtures.class_eval do
def self.create_fixtures(fixtures_directory, table_names, class_names
= {})
table_names = [table_names].flatten.map { |n| n.to_s }
connection = block_given? ? yield : ActiveRecord::Base.connection
ActiveRecord::Base.silence do
fixtures_map = {}
fixtures = table_names.map do |table_name|
fixtures_map[table_name] = Fixtures.new(connection,
File.split(table_name.to_s).last, class_names[table_name.to_sym],
File.join(fixtures_directory, table_name.to_s))
end
all_loaded_fixtures.merge! fixtures_map
connection.transaction(Thread.current['open_transactions'].to_i ==
-
do
connection.execute(“SET CONSTRAINTS ALL DEFERRED”)
fixtures.reverse.each { |fixture|
fixture.delete_existing_fixtures }
fixtures.each { |fixture| fixture.insert_fixtures }
# Cap primary key sequences to max(pk).
if connection.respond_to?(:reset_pk_sequence!)
table_names.each do |table_name|
connection.reset_pk_sequence!(table_name)
end
end
end
return fixtures.size > 1 ? fixtures : fixtures.first
end
end
end
–
Michael S.
mailto:[email protected]
http://www.schuerig.de/michael/