2

У меня есть две взаимозависимые модели, учетная запись и пользователь. Учетная запись всегда создается пользователем, идентификатор которого таким образом сохраняется в атрибуте creator_id учетной записи, и пользователь обязательно принадлежит учетной записи (но нет ограничения на количество пользователей, принадлежащих учетной записи), эта информация хранится в пользовательских account_id. Один и тот же пользователь может создать разные учетные записи.Как загрузить светильники в определенном порядке в Rails 5

Я высказал эти правила так:

модель пользователя: модель

belongs_to :account, inverse_of: :users 
has_many :created_accounts, class_name: "Account", :foreign_key => "creator_id" 

счета:

belongs_to :creator, class_name: 'User', optional: true 
has_many :users, inverse_of: :account 

Поскольку они взаимозависимы, я использовал грязный обходной путь, чтобы иметь возможность создать экземпляр они: я создаю первую учетную запись и после этого действия заставляю пользователя создавать свой профиль, а их user_id добавляется в учетную запись как creator_id в обновлении.

Вот почему у меня есть, в модели счета:

validate :require_actual_creator_id, on: :update 
------------------------------------------------ 
def require_actual_creator_id 
    User.find(creator_id) 
    end 

я работал над системой аутентификации только с участием модели пользователя, так что я имел эти строки не закомментированные до вчерашнего дня, когда я раскомментировать их.

Я побежал db: migrate: reset, db: seed и db: migrate RAILS_ENV = тест без проблем, обе модели имеют нормальное поведение в консоли, но когда дело доходит до светильников (например, тестирование или db: fixtures: нагрузки), я получил следующее сообщение об ошибке:

NoMethodError: undefined method `id' for nil:NilClass 
/home/vincent/workspace/bam-rails/test/fixtures/users.yml:16:in `get_binding' 

Вот один типичный светильник вызывает проблему, линия 16 будучи комментировал один:

michael: 
    id: 1 
    handle: Michael Example 
    email: [email protected] 
    encrypted_password: <%= User.generate_encrypted_token('password') %> 
    role_id: <%= User::ADMIN %> 
    is_activated: true 
    activated_at: <%= DateTime.now %> 
    #account_id: <%#= Account.first.id %> 

Когда я комментирую эту последнюю строку, нет никаких проблем больше. Тем не менее, я хотел бы загрузить соответствующие приборы для своих тестов, потому что, например, пользователь, созданный здесь, недействителен.

Я прочитал в this post, что светильники загружаются в алфавитном порядке. Если это правильно, я не могу понять, почему я должен прокомментировать эту строку, потому что учетные записи должны быть загружены перед пользователями.

Я нашел that solution для работы, но это не из официальной документации, и это довольно старый, датированный 2007 годом. Я боюсь, что это перестанет работать с одного дня на следующий.

Кто-нибудь знает, как правильно загрузить светильники в индивидуальном порядке в Rails 5 или есть другое решение моей проблемы? Спасибо заранее.

ответ

2

Проблема, которую вы имеете, полностью вытекает из того, как вы организовали свой код. Это работает там, где вы создаете первую учетную запись, где у вас возникла проблема. Таким образом, тот факт, что к моменту создания вашего пользователя ваша учетная запись не существует прежде всего потому, что светильники еще не загружены; из этого я уверен, что вы знаете. Светильники, как известно, хрупкие, поэтому люди часто уходят от них, чем сложнее их код. В этом случае, хотя вы поможете вам разоблачить запах кода, в любое время, когда заказ или запуск теста или базовый нестандартный тестовый пример вызывает проблемы, это означает, что у вас есть проблема с вашим кодом. Я предлагаю вам найти способ использовать эту «грязную работу».

Теперь, если по какой-то причине вы состоите в браке с тем, как ваш код в настоящее время организован, я предлагаю, возможно, перейти на factory girl, это даст вам немного больше гибкости, чтобы контролировать момент, столкнуться с этой проблемой. Я, однако, скажу, что это просто позволит вам продолжить работу по этому пути, что, скорее всего, приведет к большему количеству проблем в будущем, лучше всего переосмыслить эту функцию.

+0

Благодарим вас за ответ. Факторная девушка кажется удобной, я могу использовать ее в будущем. О том, как мой код организован, к сожалению, я не могу его изменить, потому что я не тот, кто это принимает. Однако я нашел решение моей точной проблемы, которая заключалась не в том, чтобы генерировать идентификатор с использованием erb и User.first.id, а просто писать его в виде обычного текста, например «1». Таким образом, вы не можете быть уверены, что это фактический идентификатор, и объект может быть недействительным, но, по крайней мере, есть идентификатор, и если вы тщательно управляете своими светильниками, это соответствует фактической записи. –

+0

Просто будьте предупреждены, что я использую для работы на базе кода, которая полагалась на определенные записи, находящиеся в базе данных, это привело к кошмарам буквально. Вы хотите, чтобы ваш код был как можно более безграждан, но я рад, что вы вышли из грязи. –