gpt4 book ai didi

ruby-on-rails - 唯一性验证测试的外键约束问题

转载 作者:行者123 更新时间:2023-11-29 12:52:23 25 4
gpt4 key购买 nike

运行 Rails 4.2.8

我添加了一个新模型,其 foreign_key 为 user_id。虽然在功能上一切似乎都工作正常,但当我运行一个测试来确认 user_id 的唯一性验证时,我收到了一个 ActiveRecord::InvalidForeignKey 错误。详情如下。

迁移

create_table :standard_accounts do |t|
t.timestamps null: false
t.references :user, index: true, foreign_key: true
end

模型

class StandardAccount < ActiveRecord::Base
belongs_to :user

validates_presence_of :user_id
validates_uniqueness_of :user_id
end

structure.sql(出于烦人的原因,我们使用 structure.sql 而不是模式)

ALTER TABLE ONLY public.standard_accounts
ADD CONSTRAINT fk_rails_6bc98ede2c FOREIGN KEY (user_id) REFERENCES public.users(id);

测试

RSpec.describe StripeStandardAccount, type: :model do
it { should belong_to(:user) }
it { should validate_presence_of(:user_id) }
it { should validate_uniqueness_of(:user_id) }
...

测试失败

1) StandardAccount should validate that :user_id is case-sensitively unique
Failure/Error: it { should validate_uniqueness_of(:user_id) }

ActiveRecord::InvalidForeignKey:
PG::ForeignKeyViolation: ERROR: insert or update on table "standard_accounts" violates foreign key constraint "fk_rails_6bc98ede2c"
DETAIL: Key (user_id)=(0) is not present in table "users".
: UPDATE "standard_accounts" SET "user_id" = $1, "updated_at" = $2 WHERE "standard_accounts"."id" = $3
# ./spec/models/standard_account_spec.rb:9:in `block (2 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# PG::ForeignKeyViolation:
# ERROR: insert or update on table "standard_accounts" violates foreign key constraint "fk_rails_6bc98ede2c"
# DETAIL: Key (user_id)=(0) is not present in table "users".

我想我可以编辑迁移并删除 foreign_key: true 位(这可能是在 structure.sql 中创建外键约束的原因),但它是由 Rails 默认生成器添加的,虽然我不确定它的目的是什么,但似乎这里还有其他问题,因为它应该按原样工作。

最佳答案

解决此问题的方法是在运行 shoulda 测试之前 创建 StripeStandardAccount 对象的实例。例如:

  # Step 1
# If you are using FactoryBot (note: you need to use "!" with your "let")
let!(:stripe_standard_account) { create(:stripe_standard_account) }

# If you're not using FactoryBot
StripeStandardAccount.create(your-required-params-go-here)

# Step 2
# Then run your shoulda_matcher test
it { should validate_uniqueness_of(:user_id) }

这是因为您的测试用例需要一个现有实例来与它正在创建的实例进行比较。您不能询问对象的单个实例是否唯一。 https://github.com/thoughtbot/shoulda-matchers/issues/682#issuecomment-78124438

关于ruby-on-rails - 唯一性验证测试的外键约束问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50843758/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com