Is there a way to load Rails fixtures in a specific order while running tests? For example, take the following classes...
有没有办法在运行测试时按特定顺序加载Rails灯具?例如,参加以下课程......
class User < ActiveRecord::Base
has_many :memberships
has_many :groups, through: :memberships
end
class Group < ActiveRecord::Base
has_many :memberships
has_many :users, through: :memberships
end
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :group
end
Memberships
have a database level foreign key constraint requiring Users
and Groups
to be present before they can be created. However, because Rails loads fixture alphabetically, Memberships
are loaded before Users
, and an error occurs stating the relationships do not exist (rightly so).
成员资格具有数据库级外键约束,要求用户和组在创建之前存在。但是,由于Rails按字母顺序加载fixture,因此会在Users之前加载Membership,并且会发生错误,指出关系不存在(正确地说是这样)。
ActiveRecord::InvalidForeignKey: PG::ForeignKeyViolation: ERROR: insert or update on table "memberships" violates foreign key constraint
Is there a way to load the Users
and Groups
fixtures before loading Memberships
while running tests?
有没有办法在运行测试时加载成员资格之前加载用户和组夹具?
2 个解决方案
#1
37
Your problem isn't the order that Rails is running your tests. I had the same issue as you, and after debugging for a few hours realized that ActiveRecord actually DOES disable referential integrity during insertion of fixture records to prevent these types of errors for Postgresql.
您的问题不是Rails运行测试的顺序。我遇到了和你一样的问题,经过几个小时的调试后发现,ActiveRecord实际上在插入夹具记录时会禁用参照完整性,以防止Postgresql出现这些类型的错误。
The catch is that your test database user must have superuser privileges on the test db for ActiveRecord to successfully disable referential integrity as needed for fixtures.
问题在于,您的测试数据库用户必须拥有ActiveRecord测试数据库的超级用户权限才能成功禁用fixture的参照完整性。
Here's how you fix your issue:
以下是解决问题的方法:
- Log into Postgresql with your default superuser (mine is "postgres")
- 使用默认超级用户登录Postgresql(我的是“postgres”)
-
Perform the following command:
执行以下命令:
ALTER ROLE yourtestdbuser WITH SUPERUSER;
-
Enjoy your properly working fixtures.
享受你正常工作的灯具。
The next release of Rails will have a warning (which I think is much needed) when a person is running a test database with Postgresql and a user without a superuser role. I found this on a Rails GitHub issue suggesting the warning.
当一个人使用Postgresql运行测试数据库和没有超级用户角色的用户时,Rails的下一个版本将发出警告(我认为非常需要)。我在一个Rails GitHub问题上发现了这个警告。
#2
9
Granting PostgreSQL superuser privileges to your "test" account allows Rails to work the way it wants to work. In cases where this is not desired/feasible...
向您的“测试”帐户授予PostgreSQL超级用户权限允许Rails以其想要的方式工作。在不希望/不可行的情况下......
Yes, it is possible -- if not supported -- to control the order in which fixtures are loaded and deleted (both of which are important).
是的,如果不支持,可以控制加载和删除灯具的顺序(两者都很重要)。
In test/test_helper.rb
:
在test / test_helper.rb中:
class ActiveRecord::FixtureSet
class << self
alias :orig_create_fixtures :create_fixtures
end
def self.create_fixtures f_dir, fs_names, *args
# Delete all fixtures that have foreign keys, in an order that
# doesn't break referential integrity.
Membership.delete_all
reset_cache
# If we're adding any {user, group} fixtures, add them [a] in that
# order, [b] before adding any other fixtures which might have
# references to them.
fs_names = %w(users groups) & fs_names | fs_names
orig_create_fixtures f_dir, fs_names, *args
end
end
Tested with Rails 4.2.3, and only when using fixtures :all
.
使用Rails 4.2.3进行测试,并且仅在使用fixture时:all。
#1
37
Your problem isn't the order that Rails is running your tests. I had the same issue as you, and after debugging for a few hours realized that ActiveRecord actually DOES disable referential integrity during insertion of fixture records to prevent these types of errors for Postgresql.
您的问题不是Rails运行测试的顺序。我遇到了和你一样的问题,经过几个小时的调试后发现,ActiveRecord实际上在插入夹具记录时会禁用参照完整性,以防止Postgresql出现这些类型的错误。
The catch is that your test database user must have superuser privileges on the test db for ActiveRecord to successfully disable referential integrity as needed for fixtures.
问题在于,您的测试数据库用户必须拥有ActiveRecord测试数据库的超级用户权限才能成功禁用fixture的参照完整性。
Here's how you fix your issue:
以下是解决问题的方法:
- Log into Postgresql with your default superuser (mine is "postgres")
- 使用默认超级用户登录Postgresql(我的是“postgres”)
-
Perform the following command:
执行以下命令:
ALTER ROLE yourtestdbuser WITH SUPERUSER;
-
Enjoy your properly working fixtures.
享受你正常工作的灯具。
The next release of Rails will have a warning (which I think is much needed) when a person is running a test database with Postgresql and a user without a superuser role. I found this on a Rails GitHub issue suggesting the warning.
当一个人使用Postgresql运行测试数据库和没有超级用户角色的用户时,Rails的下一个版本将发出警告(我认为非常需要)。我在一个Rails GitHub问题上发现了这个警告。
#2
9
Granting PostgreSQL superuser privileges to your "test" account allows Rails to work the way it wants to work. In cases where this is not desired/feasible...
向您的“测试”帐户授予PostgreSQL超级用户权限允许Rails以其想要的方式工作。在不希望/不可行的情况下......
Yes, it is possible -- if not supported -- to control the order in which fixtures are loaded and deleted (both of which are important).
是的,如果不支持,可以控制加载和删除灯具的顺序(两者都很重要)。
In test/test_helper.rb
:
在test / test_helper.rb中:
class ActiveRecord::FixtureSet
class << self
alias :orig_create_fixtures :create_fixtures
end
def self.create_fixtures f_dir, fs_names, *args
# Delete all fixtures that have foreign keys, in an order that
# doesn't break referential integrity.
Membership.delete_all
reset_cache
# If we're adding any {user, group} fixtures, add them [a] in that
# order, [b] before adding any other fixtures which might have
# references to them.
fs_names = %w(users groups) & fs_names | fs_names
orig_create_fixtures f_dir, fs_names, *args
end
end
Tested with Rails 4.2.3, and only when using fixtures :all
.
使用Rails 4.2.3进行测试,并且仅在使用fixture时:all。