Skip to content

Commit

Permalink
Use intermediate through factory if available
Browse files Browse the repository at this point in the history
  • Loading branch information
solnic committed Nov 3, 2023
1 parent c07d8a7 commit 858758e
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 44 deletions.
61 changes: 24 additions & 37 deletions lib/rom/factory/attributes/association.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ def dependency?(*)
def value?
false
end

# @api private
def factories
builder.factories
end
end

# @api private
Expand Down Expand Up @@ -131,42 +136,6 @@ def count
end
end

class OneToOneThrough < Core
def call(attrs = EMPTY_HASH, parent, persist: true)
return if attrs.key?(name)

struct = if persist && attrs[tpk]
attrs
elsif persist
builder.persistable.create(*traits, **attrs)
else
builder.struct(*traits, **attrs)
end

assoc.persist([parent], struct) if persist

{name => struct}
end

def dependency?(rel)
assoc.source == rel
end

def through?
true
end

private

def count
options.fetch(:count, 1)
end

def tpk
assoc.target.primary_key
end
end

class ManyToMany < Core
def call(attrs = EMPTY_HASH, parent, persist: true)

Check failure on line 140 in lib/rom/factory/attributes/association.rb

View workflow job for this annotation

GitHub Actions / Style

Style/OptionalArguments: Optional arguments should appear at the end of the argument list.
return if attrs.key?(name)
Expand All @@ -181,7 +150,14 @@ def call(attrs = EMPTY_HASH, parent, persist: true)
end
end

assoc.persist([parent], structs) if persist
# Delegate to through factory if it exists
if through_factory? && persist
structs.each do |child|
factories[through_factory_name, user: parent, address: child]
end
else
assoc.persist([parent], structs) if persist

Check failure on line 159 in lib/rom/factory/attributes/association.rb

View workflow job for this annotation

GitHub Actions / Style

Style/IfInsideElse: Convert `if` nested inside `else` to `elsif`.
end

{name => structs}
end
Expand All @@ -194,6 +170,14 @@ def through?
true
end

def through_factory?
factories.registry.key?(through_factory_name)
end

def through_factory_name
ROM::Inflector.singularize(assoc.definition.through.source).to_sym
end

private

def count
Expand All @@ -204,6 +188,9 @@ def tpk
assoc.target.primary_key
end
end

class OneToOneThrough < ManyToMany
end
end
end
end
4 changes: 4 additions & 0 deletions lib/rom/factory/builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ class Builder
# @return [Module] Custom struct namespace
option :struct_namespace, reader: false

# @!attribute [r] factories
# @return [Module] Factories with other builders
option :factories, reader: true, optional: true

# @api private
def tuple(*traits, **attrs)
tuple_evaluator.defaults(traits, attrs)
Expand Down
8 changes: 7 additions & 1 deletion lib/rom/factory/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,13 @@ def initialize(name, relation:, factories:, struct_namespace:, attributes: Attri

# @api private
def call
::ROM::Factory::Builder.new(_attributes, _traits, relation: _relation, struct_namespace: _struct_namespace)
::ROM::Factory::Builder.new(
_attributes,
_traits,
relation: _relation,
struct_namespace: _struct_namespace,
factories: _factories
)
end

# Delegate to a builder and persist a struct
Expand Down
12 changes: 12 additions & 0 deletions spec/integration/rom/factory_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@
f.association :address
end

factories.define(:user_address) do |f|
f.association(:user)
f.association(:address)
f.timestamps
end

factories.define(:address) do |f|
f.full_address "123 Elm St."
end
Expand Down Expand Up @@ -909,6 +915,12 @@ class Admin < ROM::Struct
f.association(:addresses, count: 2)
end

factories.define(:user_address) do |f|
f.association(:user)
f.association(:address)
f.timestamps
end

factories.define(:address) do |f|
f.sequence(:full_address) { |n| "Address #{n}" }
end
Expand Down
2 changes: 2 additions & 0 deletions spec/shared/relations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
primary_key :id
foreign_key :user_id, :users, on_delete: :cascade
foreign_key :address_id, :addresses, on_delete: :cascade
column :created_at, Time, null: false
column :updated_at, Time, null: false
end

conn.create_table?(:key_values) do
Expand Down
7 changes: 1 addition & 6 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,8 @@
require "pathname"
SPEC_ROOT = root = Pathname(__FILE__).dirname

begin
require "pry-byebug"
rescue LoadError
require "pry"
end

require "rom-factory"
require "byebug"
require "rspec"

Dir[root.join("support/*.rb").to_s].sort.each do |f|
Expand Down

0 comments on commit 858758e

Please sign in to comment.