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 Also known as: create

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

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

Return a new, non-persisted struct

Examples:

create a struct with default attributes

MyFactory.build(:user)

create a struct with some attributes overridden

MyFactory.build(:uesr, 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)


199
200
201
# File 'lib/rom/factory/factories.rb', line 199

def build(name, *traits, **attrs)
  structs[name, *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.



225
226
227
# File 'lib/rom/factory/factories.rb', line 225

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

#define(spec, opts = EMPTY_HASH) ⇒ 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, &)
  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, &)
    else
      relation = rom.relations[relation_name]
      DSL.new(
        name,
        relation: relation,
        factories: self,
        struct_namespace: builder_struct_namespace(namespace),
        &
      ).call
    end

  registry[name] = builder
end

#extend_builder(name, parent, relation_name, 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.



245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/rom/factory/factories.rb', line 245

def extend_builder(name, parent, relation_name, ns, &)
  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,
    &
  ).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.



230
231
232
# File 'lib/rom/factory/factories.rb', line 230

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.



235
236
237
# File 'lib/rom/factory/factories.rb', line 235

def infer_factory_name(name)
  ::ROM::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.



240
241
242
# File 'lib/rom/factory/factories.rb', line 240

def infer_relation(name)
  ::ROM::Inflector.pluralize(name).to_sym
end

#structsStructs

Return in-memory struct builder

Returns:



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

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