Skip to content

Instantly share code, notes, and snippets.

@estum
Created December 3, 2021 08:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save estum/bbefd1c496f38858daf310d62be44d65 to your computer and use it in GitHub Desktop.
Save estum/bbefd1c496f38858daf310d62be44d65 to your computer and use it in GitHub Desktop.
Dry::Initializer::ModelCoercer (instead of dry-initializer-rails)
# frozen_string_literal: true
module Dry
module Initializer
# @example
# class CreateOrder
# extend Dry::Initializer
#
# # Params and options
# param :customer, model: 'Customer' # use either a name
# option :product, model: Product # or a class
#
# def call
# Order.create customer: customer, product: product
# end
# end
#
# @api private
class ModelCoercer
# @param model [Class,ActiveRecord::Relation]
# @param find_by [Symbol,String]
# @param options [Hash]
# @return [Hash] unchanged options or options with added type coercion
def self.call(model: nil, find_by: :id, **options)
return options unless model
options.merge(type: new(model, find_by))
end
# @param model [Class,ActiveRecord::Relation]
# @param find_by [Symbol,String]
# @return [self]
def initialize(model, find_by = :id)
@model = model.is_a?(String) ? model.safe_constantize : model
@find_by = find_by
end
# @param value [ActiveRecord::Base,Integer,String]
# @return [ActiveRecord::Base]
def call(value)
return value if value.nil? || value.is_a?(klass)
@model.find_by! @find_by => value
end
private def klass
@model.is_a?(ActiveRecord::Relation) ? @model.klass : @model
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment