Ruby on rails 轨道3和x2B;rspec+;postgres:如何对具有外键约束的数据库运行测试套件?
我有一个Rails 3应用程序,它使用PostgreSQL 9.1作为数据库。我们使用RSpec和FactoryGirl进行测试 数据模型有许多1对多或多对多关系的模型,这些约束在Rails模型中使用has_-many、belish_-to、has_-many:through等进行编码。我们有这样的代码:Ruby on rails 轨道3和x2B;rspec+;postgres:如何对具有外键约束的数据库运行测试套件?,ruby-on-rails,postgresql,rspec,foreign-keys,rspec-rails,Ruby On Rails,Postgresql,Rspec,Foreign Keys,Rspec Rails,我有一个Rails 3应用程序,它使用PostgreSQL 9.1作为数据库。我们使用RSpec和FactoryGirl进行测试 数据模型有许多1对多或多对多关系的模型,这些约束在Rails模型中使用has_-many、belish_-to、has_-many:through等进行编码。我们有这样的代码: class User < ActiveRecord::Base attr_accessible :name has_many :phones end class Phone
class User < ActiveRecord::Base
attr_accessible :name
has_many :phones
end
class Phone < ActiveRecord::Base
attr_accessible :number, user_id
belongs_to :user
end
sql = "ALTER TABLE phones ADD CONSTRAINT phones_user_id FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE RESTRICT;"
ActiveRecord::Base.connection.execute(sql)
但是,我更喜欢使用外键约束在数据库中编码数据约束,而不是仅在模型中编码。为此,我创建了Rails迁移,并添加了外键约束,如下所示:
class User < ActiveRecord::Base
attr_accessible :name
has_many :phones
end
class Phone < ActiveRecord::Base
attr_accessible :number, user_id
belongs_to :user
end
sql = "ALTER TABLE phones ADD CONSTRAINT phones_user_id FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE RESTRICT;"
ActiveRecord::Base.connection.execute(sql)
当我添加外键约束,并在开发模式下启动应用程序时,数据库强制执行这些约束,并且如果用户有任何依赖的手机,我无法删除该用户。无论我是在“psql”PostgreSQL控制台还是IRB Rails控制台中,这都是正确的
然而,当我尝试编写RSpec测试以查看外键是否强制执行删除限制时,测试失败,我能够删除一个使用从属电话的用户。显然,“rakedb:test:prepare”并没有准备带有外键的数据库
有没有一种方法可以针对强制外键约束的数据库运行我的RSpec测试套件?在Rails 4中,很简单:
在config/application.rb中,设置
module YourApp
class Application < Rails::Application
config.active_record.schema_format = :sql
end
end
手动运行rake db:structure:dump
以创建db/structure.sql
,偶尔再运行一次以汇总迁移。您可以在每次迁移时修改上述内容以转储,就像Rails 4的任务一样,但是您可能会发现转储中的不重要更改会让您感到恼火
在早期版本的Rails中,甚至需要更多的黑客攻击;希望我们不必去那里
无论Rails版本如何,都值得阅读ActiveRecordGem的lib/active\u record/railties/database.rb