Class: RailsOmnibar::Command::RecordSearch

Inherits:
Search
  • Object
show all
Defined in:
lib/rails_omnibar/command/search.rb

Overview

ActiveRecord-specific search.

Instance Attribute Summary

Attributes inherited from Base

#description, #example, #if, #pattern, #resolver

Instance Method Summary collapse

Methods inherited from Base

#call, #handle?

Constructor Details

#initialize(model:, columns: :id, pattern: nil, finder: nil, itemizer: nil, example: nil, if: nil) ⇒ RecordSearch

Returns a new instance of RecordSearch.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/rails_omnibar/command/search.rb', line 32

def initialize(model:, columns: :id, pattern: nil, finder: nil, itemizer: nil, example: nil, if: nil)
  # casting and validations
  model = model.to_s.classify.constantize unless model.is_a?(Class)
  model < ActiveRecord::Base || raise(ArgumentError, 'model: must be a model')
  columns = Array(columns).map(&:to_s)
  columns.present? || raise(ArgumentError, 'columns: must be given')
  columns.each { |c| c.in?(model.column_names) || raise(ArgumentError, "bad column #{c}") }

  description = "Find #{model.name}"
  description += " by #{columns.join(' OR ')}" unless finder

  # default finder, uses LIKE/ILIKE for non-id columns
  finder ||= ->(q) do
    return model.none if q.blank?

    columns.inject(model.none) do |rel, col|
      rel.or(col =~ /id$/ ? model.where(col => q) :
                            model.where("#{col} #{RailsOmnibar.like} ?", "%#{q}%"))
    end
  end

  # default itemizer
  itemizer ||= ->(record) do
    {
      title: "#{record.class.name}##{record.id}",
      url:   "/#{model.model_name.route_key}/#{record.to_param}",
    }
  end

  super(
    description: description,
    example:     example,
    pattern:     pattern,
    finder:      finder,
    itemizer:    itemizer,
    if:          binding.local_variable_get(:if),
  )
end