Загрузка рельсов в конкретном порядке при тестировании
Есть ли способ загрузить 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
имеют ограничение уровня < уровня базы данных, требующее наличия Users
и Groups
, прежде чем они могут быть созданы. Однако, поскольку Rails загружает привязку в алфавитном порядке, Memberships
загружается до Users
, и возникает ошибка, указывающая, что отношения не существуют (правильно).
ActiveRecord::InvalidForeignKey: PG::ForeignKeyViolation: ERROR: insert or update on table "memberships" violates foreign key constraint
Есть ли способ загрузить элементы Users
и Groups
перед загрузкой Memberships
во время выполнения тестов?
Ответы
Ответ 1
Ваша проблема заключается не в том, что Rails запускает ваши тесты. У меня была такая же проблема, как и вы, и после отладки в течение нескольких часов понял, что ActiveRecord фактически отключает ссылочную целостность при вставке записей приборов, чтобы предотвратить эти типы ошибок для Postgresql.
Ловушка заключается в том, что пользователь тестовой базы данных должен иметь привилегии суперпользователя на тестовом db для ActiveRecord, чтобы успешно отключить ссылочную целостность по мере необходимости для приборов.
Вот как вы исправляете свою проблему:
- Войдите в Postgresql со своим суперпользователем по умолчанию (мой - postgres).
-
Выполните следующую команду:
ALTER ROLE yourtestdbuser WITH SUPERUSER;
-
Наслаждайтесь правильно работающими светильниками.
В следующей версии Rails появится предупреждение (которое, как мне кажется, очень необходимо), когда человек запускает тестовую базу данных с Postgresql и пользователем без роли суперпользователя. Я нашел это на проблеме Rails GitHub, предлагающей предупреждение.
Ответ 2
Предоставление привилегий суперпользователя PostgreSQL вашей учетной записи "test" позволяет Rails работать так, как она хочет работать. В тех случаях, когда это нежелательно/возможно...
Да, возможно - если не поддерживается - для управления порядком, в котором приборы загружаются и удаляются (оба из них важны).
В 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
Протестировано с Rails 4.2.3 и только при использовании fixtures :all
.