当不同的列需要相互对应时如何使用 FactoryBot 创建有效的工厂
How to create valid factories with FactoryBot when different columns need to correspond with one another
我有一个名为 Event 的模型。看起来像这样:
class Event < ApplicationRecord
belongs_to :eventable, polymorphic: true
belongs_to :user, inverse_of: :events
validates :event_category, presence: true
enum event_category: {
add_to_library: 0,
change_completion_status: 1,
favorite_game: 2,
new_user: 3,
following: 4
}
end
我 运行 遇到错误,用户可以创建 eventable
与相应类型不匹配的事件(例如 GamePurchase
表示用户库中的游戏并且是当类别为 add_to_library
时 eventable
应该是什么),因此我添加了 a Postgres check constraint 检查以确保 event_category 和 eventable_type 匹配。问题是我的事件工厂真的不喜欢这个约束,并试图在 event_category
和 eventable_type
不匹配的地方创建记录。有办法解决这个问题吗?
我的活动工厂如下所示:
FactoryBot.define do
factory :game_purchase_library_event, class: 'Event', aliases: [:event] do
user
association(:eventable, factory: :game_purchase)
event_category { :add_to_library }
end
factory :game_purchase_completion_event, class: 'Event' do
user
association(:eventable, factory: :game_purchase)
event_category { :change_completion_status }
differences do
# Pick two random values
{ completion_status: GamePurchase.completion_statuses.values.sample(2) }
end
end
factory :favorite_game_event, class: 'Event' do
user
association(:eventable, factory: :favorite_game)
event_category { :favorite_game }
end
factory :new_user_event, class: 'Event' do
user
association(:eventable, factory: :user)
event_category { :new_user }
end
factory :following_event, class: 'Event' do
user
association(:eventable, factory: :relationship)
event_category { :following }
end
end
我遇到 factory_bot 像这样的 lint 故障:
FactoryBot::InvalidFactoryError: The following factories are invalid:
* game_purchase_library_event+favorite_game - PG::CheckViolation: ERROR: new row for relation "events" violates check constraint "event_category_type_check"
DETAIL: Failing row contains (f9fb682b-8ae6-4d79-b91a-d17c58b4d02c, 29157, 4, 2021-02-28 01:05:27.591942, 2021-02-28 01:05:27.591942, 2, null, GamePurchase).
(ActiveRecord::StatementInvalid)
* game_purchase_library_event+new_user - PG::CheckViolation: ERROR: new row for relation "events" violates check constraint "event_category_type_check"
DETAIL: Failing row contains (a8de4c5c-cdc2-4bdb-9a8f-a09cf1813dac, 13791, 5, 2021-02-28 01:05:27.650202, 2021-02-28 01:05:27.650202, 3, null, GamePurchase).
(ActiveRecord::StatementInvalid)
* game_purchase_library_event+following - PG::CheckViolation: ERROR: new row for relation "events" violates check constraint "event_category_type_check"
DETAIL: Failing row contains (96d11b13-3cdd-44e2-80e5-e4a070ef8ac8, 25781, 6, 2021-02-28 01:05:27.705169, 2021-02-28 01:05:27.705169, 4, null, GamePurchase).
(ActiveRecord::StatementInvalid)
原来这是由枚举特征的自动生成引起的,这就是为什么那些不兼容的特征导致 linter 失败的原因。 is described here 功能,您可以使用 FactoryBot.automatically_define_enum_traits = false
禁用它(我在初始化目录中创建了一个 factory_bot.rb
文件并在那里禁用了它)。
我有一个名为 Event 的模型。看起来像这样:
class Event < ApplicationRecord
belongs_to :eventable, polymorphic: true
belongs_to :user, inverse_of: :events
validates :event_category, presence: true
enum event_category: {
add_to_library: 0,
change_completion_status: 1,
favorite_game: 2,
new_user: 3,
following: 4
}
end
我 运行 遇到错误,用户可以创建 eventable
与相应类型不匹配的事件(例如 GamePurchase
表示用户库中的游戏并且是当类别为 add_to_library
时 eventable
应该是什么),因此我添加了 a Postgres check constraint 检查以确保 event_category 和 eventable_type 匹配。问题是我的事件工厂真的不喜欢这个约束,并试图在 event_category
和 eventable_type
不匹配的地方创建记录。有办法解决这个问题吗?
我的活动工厂如下所示:
FactoryBot.define do
factory :game_purchase_library_event, class: 'Event', aliases: [:event] do
user
association(:eventable, factory: :game_purchase)
event_category { :add_to_library }
end
factory :game_purchase_completion_event, class: 'Event' do
user
association(:eventable, factory: :game_purchase)
event_category { :change_completion_status }
differences do
# Pick two random values
{ completion_status: GamePurchase.completion_statuses.values.sample(2) }
end
end
factory :favorite_game_event, class: 'Event' do
user
association(:eventable, factory: :favorite_game)
event_category { :favorite_game }
end
factory :new_user_event, class: 'Event' do
user
association(:eventable, factory: :user)
event_category { :new_user }
end
factory :following_event, class: 'Event' do
user
association(:eventable, factory: :relationship)
event_category { :following }
end
end
我遇到 factory_bot 像这样的 lint 故障:
FactoryBot::InvalidFactoryError: The following factories are invalid:
* game_purchase_library_event+favorite_game - PG::CheckViolation: ERROR: new row for relation "events" violates check constraint "event_category_type_check"
DETAIL: Failing row contains (f9fb682b-8ae6-4d79-b91a-d17c58b4d02c, 29157, 4, 2021-02-28 01:05:27.591942, 2021-02-28 01:05:27.591942, 2, null, GamePurchase).
(ActiveRecord::StatementInvalid)
* game_purchase_library_event+new_user - PG::CheckViolation: ERROR: new row for relation "events" violates check constraint "event_category_type_check"
DETAIL: Failing row contains (a8de4c5c-cdc2-4bdb-9a8f-a09cf1813dac, 13791, 5, 2021-02-28 01:05:27.650202, 2021-02-28 01:05:27.650202, 3, null, GamePurchase).
(ActiveRecord::StatementInvalid)
* game_purchase_library_event+following - PG::CheckViolation: ERROR: new row for relation "events" violates check constraint "event_category_type_check"
DETAIL: Failing row contains (96d11b13-3cdd-44e2-80e5-e4a070ef8ac8, 25781, 6, 2021-02-28 01:05:27.705169, 2021-02-28 01:05:27.705169, 4, null, GamePurchase).
(ActiveRecord::StatementInvalid)
原来这是由枚举特征的自动生成引起的,这就是为什么那些不兼容的特征导致 linter 失败的原因。 is described here 功能,您可以使用 FactoryBot.automatically_define_enum_traits = false
禁用它(我在初始化目录中创建了一个 factory_bot.rb
文件并在那里禁用了它)。