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


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

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

#romROM::Container (readonly)

Returns configured rom container.

Returns:

  • (ROM::Container)

    configured rom container


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

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:


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

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

Instance Method Details

#[](name, *args) ⇒ 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

  • attrs (Hash)

    An optional hash with attributes

Returns:

  • (ROM::Struct)

172
173
174
# File 'lib/rom/factory/factories.rb', line 172

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

#builder_sturct_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.


207
208
209
# File 'lib/rom/factory/factories.rb', line 207

def builder_sturct_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:


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

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_sturct_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.


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

def extend_builder(name, parent, relation_name, ns, &block)
  namespace = parent.options[:struct_namespace]
  namespace = builder_sturct_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.


212
213
214
# File 'lib/rom/factory/factories.rb', line 212

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.


217
218
219
# File 'lib/rom/factory/factories.rb', line 217

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.


222
223
224
# File 'lib/rom/factory/factories.rb', line 222

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

#structsStructs

Return in-memory struct builder

Returns:


181
182
183
# File 'lib/rom/factory/factories.rb', line 181

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