Загрузка рельсов в конкретном порядке при тестировании

Есть ли способ загрузить 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.