Class: OmniService::FindOne

Inherits:
Object
  • Object
show all
Extended by:
Dry::Initializer
Defined in:
lib/omni_service/find_one.rb

Overview

Finds a single entity by ID or attributes via repository#get_one. Skips lookup if entity already exists in context.

Options:

  • :with - param key for lookup (default: :“#context_key_id”)

  • :by - column mapping, supports nested paths: { id: [:deep, :post_id] }

  • :repository - single repo or Hash for polymorphic lookup

  • :type - path to type discriminator for polymorphic lookup

Flags:

  • :nullable - allow nil param value, returns Success(key: nil)

  • :omittable - allow missing param key, returns Success({})

  • :skippable - return Success({}) when entity not found instead of Failure

Examples:

Basic lookup

FindOne.new(:post, repository: post_repo)
# params: { post_id: 123 } => Success(post: <Post>)

Custom lookup key

FindOne.new(:post, repository: post_repo, with: :slug)
# params: { slug: 'hello' } => get_one(id: 'hello')

Nested param path

FindOne.new(:post, repository: post_repo, by: { id: [:data, :post_id] })
# params: { data: { post_id: 123 } } => get_one(id: 123)

Multi-column lookup

FindOne.new(:post, repository: post_repo, by: [:author_id, :slug])
# params: { author_id: 1, slug: 'hi' } => get_one(author_id: 1, slug: 'hi')

Polymorphic lookup

FindOne.new(:comment, repository: { 'Post' => post_repo, 'Article' => article_repo })
# params: { comment_id: 1, comment_type: 'Post' } => post_repo.get_one(id: 1)

Nullable association (for clearing)

FindOne.new(:category, repository: repo, nullable: true)
# params: { category_id: nil } => Success(category: nil)

Omittable for partial updates

FindOne.new(:category, repository: repo, omittable: true)
# params: {} => Success({}) - doesn't touch association

Skippable for soft-deleted lookups

FindOne.new(:post, repository: repo, skippable: true)
# params: { post_id: 999 } (not found) => Success({})

Constant Summary collapse

PRIMARY_KEY =
:id

Instance Method Summary collapse

Instance Method Details

#call(params, **context) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/omni_service/find_one.rb', line 69

def call(params, **context)
  return Success({}) if already_found?(context)

  missing_keys = missing_keys(params, pointers)
  return missing_keys_result(missing_keys, context) unless missing_keys.empty?

  values = values(params)
  return Success(context_key => nil) if nullable && values.all?(&:nil?)

  repository = resolve_repository(params)
  return repository_failure(params, values) unless repository

  find(values, repository:)
end