Sha256: 5771fba3afca5b137c14b39f7653fb714347f7a0eb4bdd590468ea90067394a0

Contents?: true

Size: 1.67 KB

Versions: 1

Compression:

Stored size: 1.67 KB

Contents

# frozen_string_literal: true

require "delegate"

module ROM
  module Factory
    class Builder
      # @api private
      class Persistable < SimpleDelegator
        # @api private
        attr_reader :builder

        # @api private
        attr_reader :relation

        # @api private
        def initialize(builder, relation = builder.relation)
          super(builder)
          @builder = builder
          @relation = relation
        end

        # @api private
        def create(*traits, **attrs)
          validate_keys(traits, attrs)

          tuple = tuple(*traits, **attrs)
          persisted = persist(tuple)

          if tuple_evaluator.has_associations?(traits)
            tuple_evaluator.persist_associations(tuple, persisted, traits)

            pk = primary_key_names.map { |key| persisted[key] }

            relation.by_pk(*pk).combine(*tuple_evaluator.assoc_names(traits)).first
          else
            persisted
          end
        end

        private

        # @api private
        def persist(attrs)
          result = relation
            .with(auto_struct: !tuple_evaluator.has_associations?)
            .command(:create)
            .call(attrs)

          # Handle PK values generated by the factory
          if pk? && (pks = attrs.values_at(*primary_key_names)).compact.size == primary_key_names.size
            relation.by_pk(*pks).one!
          elsif result
            result
          else
            relation.where(attrs).one!
          end
        end

        # @api private
        def primary_key_names
          relation.schema.primary_key.map(&:name)
        end

        def pk?
          primary_key_names.any?
        end
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
rom-factory-0.12.0 lib/rom/factory/builder/persistable.rb