class ROM::Factory::Factories

A registry with all configured factories

@api public

Public Instance Methods

[](name, *args) click to toggle source

Create and persist a new struct

@example create a struct with default attributes

MyFactory[:user]

@example create a struct with some attributes overridden

MyFactory[:user, name: "Jane"]

@param [Symbol] name The name of the registered factory @param [Hash] attrs An optional hash with attributes

@return [ROM::Struct]

@api public

# 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) click to toggle source

@api private

# 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) click to toggle source

Define a new builder

@example a simple builder

MyFactory.define(:user) do |f|
  f.name "Jane"
  f.email "jane@doe.org"
end

@example a builder using auto-generated fake values

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

@example a builder using sequenced values

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

@example 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

@example 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

@example 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

@example 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

@param [Symbol, Hash<Symbol=>Symbol>] spec Builder identifier, can point to a parent builder too @param [Hash] opts Additional options @option opts [Symbol] relation An optional relation name (defaults to pluralized builder name)

@return [ROM::Factory::Builder]

@api public

# 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) click to toggle source

@api private

# 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) click to toggle source

@api private

# 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) click to toggle source

@api private

# File lib/rom/factory/factories.rb, line 217
def infer_factory_name(name)
  ::Dry::Core::Inflector.singularize(name).to_sym
end
infer_relation(name) click to toggle source

@api private

# File lib/rom/factory/factories.rb, line 222
def infer_relation(name)
  ::Dry::Core::Inflector.pluralize(name).to_sym
end
struct_namespace(namespace = Undefined) click to toggle source

Get factories with a custom struct namespace

@example

EntityFactory = MyFactory.struct_namespace(MyApp::Entities)

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

@param [Module] namespace

@return [Factories]

@api public

# File lib/rom/factory/factories.rb, line 198
def struct_namespace(namespace = Undefined)
  if namespace.equal?(Undefined)
    options[:struct_namespace]
  else
    with(struct_namespace: namespace)
  end
end
structs() click to toggle source

Return in-memory struct builder

@return [Structs]

@api public

# File lib/rom/factory/factories.rb, line 181
def structs
  @__structs__ ||= Structs.new(registry, struct_namespace)
end