lib/rom/sql/plugin/associates.rb in rom-sql-3.6.4 vs lib/rom/sql/plugin/associates.rb in rom-sql-4.0.0.alpha1
- old
+ new
@@ -1,8 +1,8 @@
# frozen_string_literal: true
-require 'rom/sql/associations'
+require "rom/sql/associations"
module ROM
module SQL
module Plugin
# Make a command that automaticaly sets FK attribute on input tuples
@@ -14,61 +14,94 @@
# @api private
def initialize(name, relation, opts)
@name = name
@assoc = relation.associations[name]
- @opts = { assoc: assoc, keys: assoc.join_keys }
+ @opts = {assoc: assoc, keys: assoc.join_keys}
@opts.update(parent: opts[:parent]) if opts[:parent]
end
def after?
assoc.is_a?(SQL::Associations::ManyToMany)
end
def to_hash
- { associate: opts }
+ {associate: opts}
end
end
# @api private
def self.included(klass)
klass.class_eval do
extend ClassMethods
include InstanceMethods
- defines :associations
+ setting :associations, default: {}, reader: true
- associations Hash.new
-
option :associations, default: -> { self.class.associations }
+
option :configured_associations, default: -> { EMPTY_ARRAY }
end
super
end
# @api public
module ClassMethods
+ # @api private
+ def create_class(relation:, rel_meta: {}, parent_relation: nil, **, &block)
+ klass = super
+
+ if relation && rel_meta[:combine_type]
+ setup_associates(klass, relation, parent_relation)
+ end
+
+ klass
+ end
+
+ # Sets up `associates` plugin for a given command class and relation
+ #
+ # @param [Class] klass The command class
+ # @param [Relation] relation The relation for the command
+ #
+ # @api private
+ def setup_associates(klass, relation, parent_relation)
+ assoc_name =
+ if relation.associations.key?(parent_relation)
+ parent_relation
+ else
+ singular_name = relation.inflector.singularize(parent_relation).to_sym
+ singular_name if relation.associations.key?(singular_name)
+ end
+
+ if assoc_name
+ klass.associates(assoc_name)
+ else
+ klass.associates(parent_relation)
+ end
+ end
+
# @see ROM::Command::ClassInterface.build
#
# @api public
def build(relation, **options)
command = super
configured_assocs = command.configured_associations
associate_options = command.associations.map { |(name, opts)|
next if configured_assocs.include?(name)
+
AssociateOptions.new(name, relation, opts)
}.compact
before_hooks = associate_options.reject(&:after?).map(&:to_hash)
after_hooks = associate_options.select(&:after?).map(&:to_hash)
- command.
- with(configured_associations: configured_assocs + associate_options.map(&:name)).
- before(*before_hooks).
- after(*after_hooks)
+ command
+ .with(configured_associations: configured_assocs + associate_options.map(&:name))
+ .before(*before_hooks)
+ .after(*after_hooks)
end
# Set command to associate tuples with a parent tuple using provided keys
#
# @example
@@ -94,11 +127,13 @@
if associations.key?(name)
raise ArgumentError,
"#{name} association is already defined for #{self.class}"
end
- associations(associations.merge(name => options))
+ associations[name] = options
+
+ self
end
end
module InstanceMethods
# Set fk on tuples from parent tuple
@@ -107,10 +142,12 @@
# @param [Hash] parent The parent tuple with its pk already set
#
# @return [Array<Hash>]
#
# @api public
+ #
+ # rubocop:disable Lint/UnusedMethodArgument
def associate(tuples, curried_parent = nil, assoc:, keys:, parent: curried_parent)
result_type = result
output_tuples =
case assoc
@@ -135,9 +172,10 @@
}
end
result_type == :one ? output_tuples[0] : output_tuples
end
+ # rubocop:enable Lint/UnusedMethodArgument
# Return a new command with the provided association
#
# @param [Symbol, Relation::Name] name The name of the association
#