postgresql - Rails 3 + rspec + postgres: How to run test suite against a database with foreign key constraints? -


i have rails 3 application use postgresql 9.1 database. use rspec , factorygirl testing.

the data model has lots of models in 1-to-many or many-to-many relationships, , constraints encoded in rails models using has_many, belongs_to, has_many :through, et cetera. have code looks like:

class user < activerecord::base    attr_accessible :name    has_many :phones end  class phone < activerecord::base    attr_accessible :number, user_id    belongs_to :user end 

the schema in postgresql looks thing this

create table users (id integer, name varchar(20)); create table phones (id integer, number varchar(20), user_id integer); 

however, prefer encode data constraints in database using foreign key constraints instead of in model. this, created rails migration , added foreign key constraints doing like:

sql = "alter table phones add constraint phones_user_id foreign key (user_id) references users (id) on delete restrict;" activerecord::base.connection.execute(sql) 

when added foreign key constraints, , started application in development mode, database enforced constraints, , wasn't able delete user if had dependent phones. , held true whether in "psql" postgresql console or irb rails console.

however, when tried writing rspec test see if foreign key enforcing delete restrictions, test failed , able delete user dependent phones. apparently, "rake db:test:prepare" not prepare databases foreign keys.

is there way can run rspec test suite against database enforces foreign key constraints?

in rails 4, it's easy:

in config/application.rb, set

module yourapp   class application < rails::application     config.active_record.schema_format = :sql   end end 

rake rails_env=test db:migrate dump schema in sql db/structure.sql, , rake rails_env=test test:load load it. tasks use pg_dump postgres, they'll preserve every aspect of schema.

rails 3.2's test-database-related rake tasks didn't respect config.active_record.schema_format, didn't bother setting it. instead, overrode tasks use db:structure:load rather db:schema:load. in lib/tasks/db.rb:

namespace :db   namespace :migrate     # override original of task consistency. original, doesn't seed.     rake::task['db:migrate:reset'].clear     task reset: [ 'db:drop', 'db:create', 'db:structure:load', 'db:migrate' ]   end    # overrides original, db:schema:load. original doesn't migrate; version does,   # since, unlike schema.rb, *_structure.sql not include migrations.   rake::task['db:setup'].clear   task setup: [ 'test:ensure_environment_is_test', 'db:create', 'db:structure:load', 'db:migrate', 'db:seed' ]    rake::task['db:reset'].clear   task reset: [ 'test:ensure_environment_is_test', 'db:drop', 'db:setup' ]    namespace :test     desc "rspec tasks depend on task, override set database in way want."     rake::task['db:test:prepare'].clear     task prepare: [ 'db:reset' ]   end  end  namespace :test   task :ensure_environment_is_test     raise "don't know how db:setup rails_env=#{rails.env}" unless rails.env.test?   end end 

run rake db:structure:dump manually create db/structure.sql, , again roll migrations. modify above dump every time migrate, rails 4's tasks do, might or might not find inconsequential changes in dump make annoying.

even more hacking necessary in earlier versions of rails; hope don't have go there.

regardless of rails version, it's worth reading activerecord gem's lib/active_record/railties/database.rb.


Comments

Popular posts from this blog

javascript - RequestAnimationFrame not working when exiting fullscreen switching space on Safari -

Python ctypes access violation with const pointer arguments -