Class: FactoryBot::DefinitionProxy
- Inherits:
-
Object
- Object
- FactoryBot::DefinitionProxy
- Defined in:
- lib/factory_bot/definition_proxy.rb
Constant Summary collapse
- UNPROXIED_METHODS =
%w(__send__ __id__ nil? send object_id extend instance_eval initialize block_given? raise caller method)
Instance Attribute Summary collapse
-
#child_factories ⇒ Object
readonly
Returns the value of attribute child_factories.
Instance Method Summary collapse
-
#add_attribute(name, value = nil, &block) ⇒ Object
Adds an attribute that should be assigned on generated instances for this factory.
-
#association(name, *options) ⇒ Object
Adds an attribute that builds an association.
- #factory(name, options = {}, &block) ⇒ Object
- #ignore(&block) ⇒ Object
-
#initialize(definition, ignore = false) ⇒ DefinitionProxy
constructor
A new instance of DefinitionProxy.
- #initialize_with(&block) ⇒ Object
-
#method_missing(name, *args, &block) ⇒ Object
Calls add_attribute using the missing method name as the name of the attribute, so that:.
-
#sequence(name, *args, &block) ⇒ Object
Adds an attribute that will have unique values generated by a sequence with a specified format.
- #singleton_method_added(name) ⇒ Object
- #skip_create ⇒ Object
- #to_create(&block) ⇒ Object
- #trait(name, &block) ⇒ Object
- #transient(&block) ⇒ Object
Constructor Details
#initialize(definition, ignore = false) ⇒ DefinitionProxy
Returns a new instance of DefinitionProxy.
13 14 15 16 17 |
# File 'lib/factory_bot/definition_proxy.rb', line 13 def initialize(definition, ignore = false) @definition = definition @ignore = ignore @child_factories = [] end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
Calls add_attribute using the missing method name as the name of the attribute, so that:
factory :user do
name 'Billy Idol'
end
and:
factory :user do
add_attribute :name, 'Billy Idol'
end
are equivalent.
If no argument or block is given, factory_bot will look for a sequence or association with the same name. This means that:
factory :user do
email { create(:email) }
association :account
end
and:
factory :user do
email
account
end
are equivalent.
97 98 99 100 101 102 103 104 105 |
# File 'lib/factory_bot/definition_proxy.rb', line 97 def method_missing(name, *args, &block) if args.empty? && block.nil? @definition.declare_attribute(Declaration::Implicit.new(name, @definition, @ignore)) elsif args.first.respond_to?(:has_key?) && args.first.has_key?(:factory) association(name, *args) else add_attribute(name, *args, &block) end end |
Instance Attribute Details
#child_factories ⇒ Object (readonly)
Returns the value of attribute child_factories.
11 12 13 |
# File 'lib/factory_bot/definition_proxy.rb', line 11 def child_factories @child_factories end |
Instance Method Details
#add_attribute(name, value = nil, &block) ⇒ Object
Adds an attribute that should be assigned on generated instances for this factory.
This method should be called with either a value or block, but not both. If called with a block, the attribute will be generated “lazily,” whenever an instance is generated. Lazy attribute blocks will not be called if that attribute is overridden for a specific instance.
When defining lazy attributes, an instance of FactoryBot::Strategy will be yielded, allowing associations to be built using the correct build strategy.
Arguments:
-
name:
Symbol
orString
The name of this attribute. This will be assigned using “name=” for generated instances. -
value:
Object
If no block is given, this value will be used for this attribute.
42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/factory_bot/definition_proxy.rb', line 42 def add_attribute(name, value = nil, &block) raise AttributeDefinitionError, 'Both value and block given' if value && block_given? declaration = if block_given? Declaration::Dynamic.new(name, @ignore, block) else warn_static_attribute_deprecation(name, value) Declaration::Static.new(name, value, @ignore) end @definition.declare_attribute(declaration) end |
#association(name, *options) ⇒ Object
Adds an attribute that builds an association. The associated instance will be built using the same build strategy as the parent instance.
Example:
factory :user do
name 'Joey'
end
factory :post do
association :author, factory: :user
end
Arguments:
-
name:
Symbol
The name of this attribute. -
options:
Hash
Options:
-
factory:
Symbol
orString
The name of the factory to use when building the associated instance. If no name is given, the name of the attribute is assumed to be the name of the factory. For example, a "user" association will by default use the "user" factory.
151 152 153 |
# File 'lib/factory_bot/definition_proxy.rb', line 151 def association(name, *) @definition.declare_attribute(Declaration::Association.new(name, *)) end |
#factory(name, options = {}, &block) ⇒ Object
163 164 165 |
# File 'lib/factory_bot/definition_proxy.rb', line 163 def factory(name, = {}, &block) @child_factories << [name, , block] end |
#ignore(&block) ⇒ Object
55 56 57 58 59 |
# File 'lib/factory_bot/definition_proxy.rb', line 55 def ignore(&block) ActiveSupport::Deprecation.warn "`#ignore` is deprecated and will be "\ "removed in 5.0. Please use `#transient` instead." transient(&block) end |
#initialize_with(&block) ⇒ Object
171 172 173 |
# File 'lib/factory_bot/definition_proxy.rb', line 171 def initialize_with(&block) @definition.define_constructor(&block) end |
#sequence(name, *args, &block) ⇒ Object
Adds an attribute that will have unique values generated by a sequence with a specified format.
The result of:
factory :user do
sequence(:email) { |n| "person#{n}@example.com" }
end
Is equal to:
sequence(:email) { |n| "person#{n}@example.com" }
factory :user do
email { FactoryBot.generate(:email) }
end
Except that no globally available sequence will be defined.
123 124 125 126 |
# File 'lib/factory_bot/definition_proxy.rb', line 123 def sequence(name, *args, &block) sequence = Sequence.new(name, *args, &block) add_attribute(name) { increment_sequence(sequence) } end |
#singleton_method_added(name) ⇒ Object
19 20 21 22 |
# File 'lib/factory_bot/definition_proxy.rb', line 19 def singleton_method_added(name) = "Defining methods in blocks (trait or factory) is not supported (#{name})" raise FactoryBot::MethodDefinitionError, end |
#skip_create ⇒ Object
159 160 161 |
# File 'lib/factory_bot/definition_proxy.rb', line 159 def skip_create @definition.skip_create end |
#to_create(&block) ⇒ Object
155 156 157 |
# File 'lib/factory_bot/definition_proxy.rb', line 155 def to_create(&block) @definition.to_create(&block) end |
#trait(name, &block) ⇒ Object
167 168 169 |
# File 'lib/factory_bot/definition_proxy.rb', line 167 def trait(name, &block) @definition.define_trait(Trait.new(name, &block)) end |
#transient(&block) ⇒ Object
61 62 63 64 |
# File 'lib/factory_bot/definition_proxy.rb', line 61 def transient(&block) proxy = DefinitionProxy.new(@definition, true) proxy.instance_eval(&block) end |