Class: ROM::Factory::Factories

Inherits:
Object
  • Object
show all
Extended by:
Dry::Configurable, Initializer
Defined in:
lib/rom/factory/factories.rb

Overview

A registry with all configured factories

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#registryHash<Symbol=>Builder> (readonly)

Returns a map with defined db-backed builders.

Returns:

  • (Hash<Symbol=>Builder>)

    a map with defined db-backed builders



65
# File 'lib/rom/factory/factories.rb', line 65

option :registry, default: proc { Registry.new }

#romROM::Container (readonly)

Returns configured rom container.

Returns:

  • (ROM::Container)

    configured rom container



57
# File 'lib/rom/factory/factories.rb', line 57

param :rom

#struct_namespace(namespace = Undefined) ⇒ Factories (readonly)

Get factories with a custom struct namespace

Examples:

EntityFactory = MyFactory.struct_namespace(MyApp::Entities)

EntityFactory[:user]
# => #<MyApp::Entities::User id=2 ...>

Parameters:

  • namespace (Module) (defaults to: Undefined)

Returns:



61
# File 'lib/rom/factory/factories.rb', line 61

option :struct_namespace, optional: true, default: proc { ROM::Struct }

Instance Method Details

#[](name, *traits, **attrs) ⇒ ROM::Struct

Create and persist a new struct

Examples:

create a struct with default attributes

MyFactory[:user]

create a struct with some attributes overridden

MyFactory[:user, name: "Jane"]

Parameters:

  • name (Symbol)

    The name of the registered factory

  • traits (Array<Symbol>)

    List of traits to apply

  • attrs (Hash)

    optional attributes to override the defaults

Returns:

  • (ROM::Struct)


170
171
172
# File 'lib/rom/factory/factories.rb', line 170

def [](name, *traits, **attrs)
  registry[name].struct_namespace(struct_namespace).persistable.create(*traits, **attrs)
end

#builder_struct_namespace(ns) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



205
206
207
# File 'lib/rom/factory/factories.rb', line 205

def builder_struct_namespace(ns)
  ns ? {namespace: ns, overridable: false} : {namespace: struct_namespace, overridable: true}
end

#define(spec, opts = EMPTY_HASH, &block) ⇒ ROM::Factory::Builder

Define a new builder

Examples:

a simple builder

MyFactory.define(:user) do |f|
  f.name "Jane"
  f.email "[email protected]"
end

a builder using auto-generated fake values

MyFactory.define(:user) do |f|
  f.name { fake(:name) }
  f.email { fake(:internet, :email) }
end

a builder using sequenced values

MyFactory.define(:user) do |f|
  f.sequence(:name) { |n| "user-#{n}" }
end

a builder using values from other attribute(s)

MyFactory.define(:user) do |f|
  f.name "Jane"
  f.email { |name| "#{name.downcase}@rom-rb.org" }
end

a builder with "belongs-to" association

MyFactory.define(:group) do |f|
  f.name "Admins"
end

MyFactory.define(:user) do |f|
  f.name "Jane"
  f.association(:group)
end

a builder with "has-many" association

MyFactory.define(:group) do |f|
  f.name "Admins"
  f.association(:users, count: 2)
end

MyFactory.define(:user) do |f|
  f.sequence(:name) { |n| "user-#{n}" }
end

a builder which extends another builder

MyFactory.define(:user) do |f|
  f.name "Jane"
  f.admin false
end

MyFactory.define(admin: :user) do |f|
  f.admin true
end

Parameters:

  • spec (Symbol, Hash<Symbol=>Symbol>)

    Builder identifier, can point to a parent builder too

  • opts (Hash) (defaults to: EMPTY_HASH)

    Additional options

Options Hash (opts):

  • relation (Symbol)

    An optional relation name (defaults to pluralized builder name)

Returns:



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/rom/factory/factories.rb', line 129

def define(spec, opts = EMPTY_HASH, &block)
  name, parent = spec.is_a?(Hash) ? spec.flatten(1) : spec
  namespace = opts[:struct_namespace]
  relation_name = opts.fetch(:relation) { infer_relation(name) }

  if registry.key?(name)
    raise ArgumentError, "#{name.inspect} factory has been already defined"
  end

  builder =
    if parent
      extend_builder(name, registry[parent], relation_name, namespace, &block)
    else
      relation = rom.relations[relation_name]
      DSL.new(
        name,
        relation: relation,
        factories: self,
        struct_namespace: builder_struct_namespace(namespace),
        &block
      ).call
    end

  registry[name] = builder
end

#extend_builder(name, parent, relation_name, ns, &block) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/rom/factory/factories.rb', line 225

def extend_builder(name, parent, relation_name, ns, &block)
  namespace = parent.options[:struct_namespace]
  namespace = builder_struct_namespace(ns) if ns
  relation = rom.relations.fetch(relation_name) { parent.relation }
  DSL.new(
    name,
    attributes: parent.attributes,
    relation: relation,
    factories: self,
    struct_namespace: namespace,
    &block
  ).call
end

#for_relation(relation) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



210
211
212
# File 'lib/rom/factory/factories.rb', line 210

def for_relation(relation)
  registry[infer_factory_name(relation.name.to_sym)]
end

#infer_factory_name(name) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



215
216
217
# File 'lib/rom/factory/factories.rb', line 215

def infer_factory_name(name)
  ::Dry::Core::Inflector.singularize(name).to_sym
end

#infer_relation(name) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



220
221
222
# File 'lib/rom/factory/factories.rb', line 220

def infer_relation(name)
  ::Dry::Core::Inflector.pluralize(name).to_sym
end

#structsStructs

Return in-memory struct builder

Returns:



179
180
181
# File 'lib/rom/factory/factories.rb', line 179

def structs
  @__structs__ ||= Structs.new(registry, struct_namespace)
end