mirror of
https://github.com/thoughtbot/factory_bot.git
synced 2022-11-09 11:43:51 -05:00
975fc4ff29
## Enum traits
Given a Rails model with an enum attribute:
```rb
class Task < ActiveRecord::Base
enum status: {queued: 0, started: 1, finished: 2}
end
```
It is common for people to define traits for each possible value of the enum:
```rb
FactoryBot.define do
factory :task do
trait :queued do
status { :queued }
end
trait :started do
status { :started }
end
trait :finished do
status { :finished }
end
end
end
```
With this commit, those trait definitions are no longer necessary—they are defined automatically by factory_bot.
If automatically defining traits for enum attributes on every factory is not desired, it is possible to disable the feature by setting `FactoryBot.automatically_define_enum_traits = false` (see commit: [Allow opting out of automatically defining traits](5a20017351
)).
In that case, it is still possible to explicitly define traits for an enum attribute in a particular factory:
```rb
FactoryBot.automatically_define_enum_traits = false
FactoryBot.define do
factory :task do
traits_for_enum(:status)
end
end
```
It is also possible to use this feature for other enumerable values, not specifically tied to ActiveRecord enum attributes:
```rb
class Task
attr_accessor :status
end
FactoryBot.define do
factory :task do
traits_for_enum(:status, ["queued", "started", "finished"])
end
end
```
The second argument here can be an enumerable object, including a Hash or Array.
Closes #1049
Co-authored-by: Lance Johnson <lancejjohnson@gmail.com>
Co-authored-by: PoTa <pota@mosfet.hu>
Co-authored-by: Frida Casas <fridacasas.fc@gmail.com>
Co-authored-by: Daniel Colson <danieljamescolson@gmail.com>
27 lines
608 B
Ruby
27 lines
608 B
Ruby
module FactoryBot
|
|
# @api private
|
|
class Enum
|
|
def initialize(attribute_name, values = nil)
|
|
@attribute_name = attribute_name
|
|
@values = values
|
|
end
|
|
|
|
def build_traits(klass)
|
|
enum_values(klass).map do |trait_name, value|
|
|
build_trait(trait_name, @attribute_name, value || trait_name)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def enum_values(klass)
|
|
@values || klass.send(@attribute_name.to_s.pluralize)
|
|
end
|
|
|
|
def build_trait(trait_name, attribute_name, value)
|
|
Trait.new(trait_name) do
|
|
add_attribute(attribute_name) { value }
|
|
end
|
|
end
|
|
end
|
|
end
|