Ноль Ассоциации с Rails Fixtures ... как исправить? - PullRequest
0 голосов
/ 24 мая 2018

У меня есть проект Rails 5.1, использующий rspec / fixtures, и у меня возникают проблемы с получением приспособлений для загрузки объектов, связанных с assign_to / has_one / has_many: объект, для которого я запросил это приспособление, возвращается с его столбцами _id, заполненными на первый взгляд случайныминомер и ActiveRecord видит ассоциацию как nil.Это происходит в больших классах со многими ассоциациями, а также в небольших классах данных с несколькими полями.

Если в моем тестовом коде я назначу эти ассоциации нормальному коду Ruby, объекты будут вести себя как обычно, и мои тесты пройдут.Однако при загрузке одних и тех же данных через фикстуры соответствующие записи недоступны, и тесты, требующие охвата данных между ассоциациями, не пройдены.

Например, здесь есть два затронутых класса:

#app/models/location.rb
class Location < ActiveRecord::Base
  has_many :orders
  has_many :end_user
  belongs_to :retailer
  belongs_to :depot
end

#app/models/retailer.rb
class Retailer < ActiveRecord::Base
    has_many :locations
end

ИВот два соответствующих файла осветителей:

#spec/fixtures/locations.yml
loc_paris:
  retailer: ret_europe (Retailer)
  name: "Paris"
  nickname: "paris"

loc_washington:
  retailer: ret_usa (Retailer)
  name: "Washington"
  nickname: "washington"

#spec/fixtures/retailers.yml
ret_europe:
  name: "AcmeCo France"
  nickname: "acmecofr"
  currency_type: "EUR"

ret_usa:
  name: "AcmeCo USA"
  nickname: "acmecousa"
  currency_type: "USD"

С приведенными выше данными, выполнение pp locations(:loc_paris) приводит к:

#<Location:0x0000000006eee1d8
 id: 35456173,
 name: "Paris",
 nickname: "paris",
 retailer_id: 399879241,
 created_at: Wed, 23 May 2018 22:39:56 UTC +00:00,
 updated_at: Wed, 23 May 2018 22:39:56 UTC +00:00>

Эти идентификаторы соответствуют нескольким вызовам, по крайней мере, втот же контекст RSpec.(Я поместил pp locations(:loc_paris) в блок let.) И все же pp locations(:loc_paris).retailer возвращает nil.

Я пытался использовать FactoryBot, однако нам пришлось от него отказаться.Я пытаюсь честно встряхнуть приборы, но кажется, что нам лучше всего просто строить объекты данных в реальном тестовом коде ... потому что эти решения работают без жалоб: /

Я что-то здесь не так делаю?Мы просим слишком много приспособлений?

Спасибо!

Том

1 Ответ

0 голосов
/ 24 мая 2018

Проблема с приборами

Глядя на то, что вы сделали, locations(:loc_paris) найдет запись, описанную в location.yml , но locations(:loc_paris).retailer выиграно't.

Rails Ассоциации работают так:

locations(:loc_paris).retailer будет искать retailer с retailer_id, упомянутым в записи locations(:loc_paris).В вашем случае retailer_id: 399879241, а с этим id нет reseller, поэтому он возвращает Nil.

Решение: Опишите приборы следующим образом:

#spec/fixtures/locations.yml
loc_paris:
  retailer_id: 1
  name: "Paris"
  nickname: "paris"

loc_washington:
  retailer_id: 2
  name: "Washington"
  nickname: "washington"

#spec/fixtures/retailers.yml
ret_europe:
  id: 1
  name: "AcmeCo France"
  nickname: "acmecofr"
  currency_type: "EUR"

ret_usa:
  id: 2
  name: "AcmeCo USA"
  nickname: "acmecousa"
  currency_type: "USD"

Теперь locations(:loc_paris).retailer будет искать продавца с retailer_id, упомянутым в записи locations(:loc_paris), т.е. retailer_id: 1, и есть реселлер ret_europe с этим id. Проблема решена

Когда вы запускаете rspec, сначала rspec сохраняет эти приборы в вашу базу данных с некоторыми автоматически сгенерированными значениями id (если id не указано явно), поэтому id и reseller_id являются случайными значениями .Если вы не хотите, чтобы запись id из locations.yml была какой-то случайной величиной, вы можете предоставить ее себе так:

loc_paris:
  id: 1
  retailer_id: 1
  name: "Paris"
  nickname: "paris"

Советы: Как rspecработает в среде test (упоминаемой в app / spec / rails_helper.rb ) и, как я упоминал ранее, когда вы запускаете rspec, сначала он сохраняет данные в вашей базе данных.Если ваша база данных local и test совпадает, данные заменится фактическими записями базы данных вашей базы данных.В вашем случае записи в таблице locations и resellers будут полностью удалены и заменены этими приборами.Итак, создайте другую базу данных для test среды.

Надеюсь, этот ответ полезен

...