PG :: ForeignKeyViolation: ОШИБКА после изменения ассоциации has_and_belongs_to_many в рельсах на ассоциацию has_many: through - PullRequest
0 голосов
/ 22 сентября 2019

Недавно я переключил ассоциацию has_and_belongs_to_many (HABTM) на ассоциацию has_many :through, и теперь у меня много неудачных тестов из-за нарушения ограничений внешнего ключа.Вот пример сообщения об ошибке теста:

DRb::DRbRemoteError: PG::ForeignKeyViolation: ERROR:  update or delete on table "choices" violates foreign key constraint "fk_rails_d6ffbc38aa" on table "selections"
        DETAIL:  Key (id)=(506907318) is still referenced from table "selections"

Вот форма, которая создает связь.screenshot of my form

Вот мои модели с соответствующими ассоциациями ...

models/variant.rb

class Variant < ApplicationRecord    
  has_many :selections
  has_many :choices, through: :selections
end

models/choice.rb

class Choice < ApplicationRecord
  has_many :variants, through: :selections

  belongs_to :option
end

models/selection.rb

class Selection < ApplicationRecord
  belongs_to :choice
  belongs_to :variant
end

И соответствующие схемы:

create_table "variants", force: :cascade do |t|
  t.string "sku"
  t.datetime "created_at", precision: 6, null: false
  t.datetime "updated_at", precision: 6, null: false
  t.bigint "account_id"
  t.bigint "product_id"
  t.index ["account_id"], name: "index_variants_on_account_id"
  t.index ["product_id"], name: "index_variants_on_product_id"
end

create_table "choices", force: :cascade do |t|
  t.string "name"
  t.datetime "created_at", precision: 6, null: false
  t.datetime "updated_at", precision: 6, null: false
  t.bigint "option_id"
  t.bigint "account_id"
  t.index ["account_id"], name: "index_choices_on_account_id"
  t.index ["option_id"], name: "index_choices_on_option_id"
end

create_table "selections", force: :cascade do |t|
  t.bigint "choice_id"
  t.bigint "variant_id"
  t.datetime "created_at", precision: 6
  t.datetime "updated_at", precision: 6
  t.index ["choice_id"], name: "index_selections_on_choice_id"
  t.index ["variant_id"], name: "index_selections_on_variant_id"
end

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

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

Я использую приборы для своих тестов.Это проблема?Есть ли что-то в моих приборах, что может быть причиной этой ошибки?К вашему сведению, я хочу продолжать использовать светильники и не переключать приложение на фабрики.

test/fixtures/variants.yml

small_t_shirt_in_red:
  id: 1
  account: fuzz
  product: t_shirt
  sku: FUZZ-T-001
  choices: small, red

medium_generic_gadget_in_blue:
  id: 2
  account: generic_gadgets
  product: gadget
  sku: GENERIC-001
  choices: medium, blue


test/fixtures/choices.yml

small:
  name: Small

medium:
  name: Medium

large:
  name: Large

red:
  name: Red

blue:
  name: Blue


test/fixtures/selections.yml

small_t_shirt_selection:
  choice_id: 1
  variant_id: 1

red_t_shirt_selection:
  choice_id: 4
  variant_id: 1

medium_generic_selection:
  choice_id: 2
  variant_id: 2

blue_generic_selection:
  choice_id: 5
  variant_id: 2

Ответы [ 2 ]

0 голосов
/ 23 сентября 2019

Обновление

Я выяснил проблему, поэтому разместил решение здесь на тот случай, если кому-то еще это понадобится.

Вот исправления, которые сработали:

test/fixtures/variants.yml

small_t_shirt_in_red:
  account: fuzz
  product: t_shirt
  sku: FUZZ-T-001
  choices: small, red

medium_generic_gadget_in_blue:
  account: generic_gadgets
  product: gadget
  sku: GENERIC-001
  choices: medium, blue


test/fixtures/choices.yml

small:
  name: Small

medium:
  name: Medium

large:
  name: Large

red:
  name: Red

blue:
  name: Blue


test/fixtures/selections.yml

red_t_shirt_selection:
  choice: red
  variant: small_t_shirt_in_red

medium_generic_selection:
  choice: medium
  variant: medium_generic_gadget_in_blue

Затем мне нужно было обновить мои модели до этого:

models/variant.rb

class Variant < ApplicationRecord
  has_many :selections, dependent: :destroy
  has_many :choices, through: :selections
end


models/choice.rb

class Choice < ApplicationRecord
  has_many :selections, dependent: :destroy
  has_many :variants, through: :selections

  belongs_to :option
end


models/selection.rb

class Selection < ApplicationRecord
  belongs_to :choice
  belongs_to :variant
end

Мне не хватало has_many :selections, dependent: :destroy на обеих моделях Variant и Choice.

0 голосов
/ 22 сентября 2019

Попробуйте сбросить и заново создать тестовую БД:

RAILS_ENV=test rails db:drop db:create

Возможно, у тестовой БД есть ограничение внешнего ключа, которого нет у основной / dev БД.

...