为包含查询数据库的回调的 Rails 模型创建 FactoryGirl 工厂
Create FactoryGirl factory for Rails Model that Contains Callback that Queries DB
我定义了以下用户模型,在创建新用户后,默认记录被插入到用户和个性类型之间的连接 table 中(是的......我知道默认个性是老土):
class User < ActiveRecord::Base
before_create :assign_default_personality_type
has_many :personality_types, through: :personality_types_users
has_many :personality_types_users, dependent: :destroy
#using nested_forms gem
accepts_nested_attributes_for :personality_types_users
# When creating user, assign all to 'Loving' personality type by default
def assign_default_personality_type
if self.new_record?
self.personality_types_attributes = [{ personality_type_id: PersonalityType.find_by_name('Loving').id }]
end
end
这是我的 personality_type 模型
class PersonalityType < ActiveRecord::Base
has_many :users, through: :personality_types_users
has_many :personality_types
我有一个连接模型 table class
class PersonalityTypesUser < ActiveRecord::Base
belongs_to :user
belongs_to :personality_type
我的问题是通过 FactoryGirl 构建用户工厂。因为我有一个 before_create
回调链接到 User
,当我尝试通过 FactoryGirl 建立一个新用户时,我收到以下错误:
Failure/Error: self.personality_types_attributes = [{ personality_type_id: PersonalityType.find_by_name('Loving').id }]
NoMethodError:
undefined method `id' for nil:NilClass
我明白了,当通过 FactoryGirl 构建用户时,测试数据库中没有 Loving
性格类型的数据。我 喜欢 就此事寻求帮助。这是我现有的工厂
FactoryGirl.define do
factory :user do
first_name { Faker::Name.first_name }
last_name { Faker::Name.last_name }
after(:build) do |em, evaluator|
...
end
FactoryGirl.define do
factory :personality_type do
name { Faker::Lorem.characters(number: 6) }
factory :loving_personality_type do
name 'Loving'
end
FactoryGirl.define do
factory :personality_types_user do
association :personality_type
association :user
end
总而言之,我的问题是如何在创建用户之前让 Loving
personality_type 存在,以便在调用模型中的回调时,它有一个个性 ID找到了吗?
当我在用户模型中添加以下 FactoryGirl 回调时,似乎有点工作
after(:build) do |em, evaluator|
loving_personality_type = PersonalityType.new(name: 'Loving')
loving_personality_type.save
end
但这适用于独立的单元测试。当我 运行 整个规范模型文件时,它有很多测试,其中用户是在几个测试中构建和创建的,我得到
Failure/Error: loving_personality_type.save
ActiveRecord::RecordNotUnique:
PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_personality_types_on_name"
DETAIL: Key (name)=(Loving) already exists.
: INSERT INTO "personality_types" ("name", "created_at", "updated_at") VALUES (, , ) RETURNING "id"
我期望 FactoryGirl 能够创建具有 'Loving' 个性类型关联的用户。我不想遍历整个代码库,在创建用户的每个 RSpec 文件中定义个性类型。感谢所有帮助。
你可以在工厂的after(:build)
块中使用find_or_create_by
。
after(:build) do |em, evaluator|
loving_personality_type = PersonalityType.find_or_create_by(name: 'Loving')
loving_personality_type.save
end
如果数据库中存在,这基本上不会创建新的 PersonalityType
。但是,return 它是 loving_personality_type
变量的实例。
在我看来,这应该可以解决您的问题。
您可以在这里阅读更多内容:https://apidock.com/rails/v4.0.2/ActiveRecord/Relation/find_or_create_by
我定义了以下用户模型,在创建新用户后,默认记录被插入到用户和个性类型之间的连接 table 中(是的......我知道默认个性是老土):
class User < ActiveRecord::Base
before_create :assign_default_personality_type
has_many :personality_types, through: :personality_types_users
has_many :personality_types_users, dependent: :destroy
#using nested_forms gem
accepts_nested_attributes_for :personality_types_users
# When creating user, assign all to 'Loving' personality type by default
def assign_default_personality_type
if self.new_record?
self.personality_types_attributes = [{ personality_type_id: PersonalityType.find_by_name('Loving').id }]
end
end
这是我的 personality_type 模型
class PersonalityType < ActiveRecord::Base
has_many :users, through: :personality_types_users
has_many :personality_types
我有一个连接模型 table class
class PersonalityTypesUser < ActiveRecord::Base
belongs_to :user
belongs_to :personality_type
我的问题是通过 FactoryGirl 构建用户工厂。因为我有一个 before_create
回调链接到 User
,当我尝试通过 FactoryGirl 建立一个新用户时,我收到以下错误:
Failure/Error: self.personality_types_attributes = [{ personality_type_id: PersonalityType.find_by_name('Loving').id }]
NoMethodError:
undefined method `id' for nil:NilClass
我明白了,当通过 FactoryGirl 构建用户时,测试数据库中没有 Loving
性格类型的数据。我 喜欢 就此事寻求帮助。这是我现有的工厂
FactoryGirl.define do
factory :user do
first_name { Faker::Name.first_name }
last_name { Faker::Name.last_name }
after(:build) do |em, evaluator|
...
end
FactoryGirl.define do
factory :personality_type do
name { Faker::Lorem.characters(number: 6) }
factory :loving_personality_type do
name 'Loving'
end
FactoryGirl.define do
factory :personality_types_user do
association :personality_type
association :user
end
总而言之,我的问题是如何在创建用户之前让 Loving
personality_type 存在,以便在调用模型中的回调时,它有一个个性 ID找到了吗?
当我在用户模型中添加以下 FactoryGirl 回调时,似乎有点工作
after(:build) do |em, evaluator|
loving_personality_type = PersonalityType.new(name: 'Loving')
loving_personality_type.save
end
但这适用于独立的单元测试。当我 运行 整个规范模型文件时,它有很多测试,其中用户是在几个测试中构建和创建的,我得到
Failure/Error: loving_personality_type.save
ActiveRecord::RecordNotUnique:
PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_personality_types_on_name"
DETAIL: Key (name)=(Loving) already exists.
: INSERT INTO "personality_types" ("name", "created_at", "updated_at") VALUES (, , ) RETURNING "id"
我期望 FactoryGirl 能够创建具有 'Loving' 个性类型关联的用户。我不想遍历整个代码库,在创建用户的每个 RSpec 文件中定义个性类型。感谢所有帮助。
你可以在工厂的after(:build)
块中使用find_or_create_by
。
after(:build) do |em, evaluator|
loving_personality_type = PersonalityType.find_or_create_by(name: 'Loving')
loving_personality_type.save
end
如果数据库中存在,这基本上不会创建新的 PersonalityType
。但是,return 它是 loving_personality_type
变量的实例。
在我看来,这应该可以解决您的问题。
您可以在这里阅读更多内容:https://apidock.com/rails/v4.0.2/ActiveRecord/Relation/find_or_create_by