Class: Paraphrase::Query

Inherits:
Object
  • Object
show all
Defined in:
lib/paraphrase/query.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params, class_or_relation) ⇒ Query

Filters out parameters irrelevant to the query and sets the base scope for to begin the chain.

Parameters:

  • params (Hash)

    query parameters

  • source (ActiveRecord::Base, ActiveRecord::Relation)

    object to apply methods to



45
46
47
48
49
50
51
52
53
# File 'lib/paraphrase/query.rb', line 45

def initialize(params, class_or_relation)
  keys = mappings.map(&:keys).flatten.map(&:to_s)

  @params = HashWithIndifferentAccess.new(params)
  @params.select! { |key, value| keys.include?(key) && value.present? }
  @params.freeze

  @source = class_or_relation
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object (protected)



78
79
80
81
82
83
84
85
# File 'lib/paraphrase/query.rb', line 78

def method_missing(name, *args, &block)
  if results.respond_to?(name)
    self.class.delegate name, :to => :results
    results.send(name, *args, &block)
  else
    super
  end
end

Instance Attribute Details

#mappingsArray<ScopeMapping> (readonly)

Returns mappings for query.

Returns:



11
# File 'lib/paraphrase/query.rb', line 11

class_attribute :mappings, :instance_writer => false

#paramsHashWithIndifferentAccess (readonly)

Returns filters parameters based on keys defined in mappings.

Returns:

  • (HashWithIndifferentAccess)

    filters parameters based on keys defined in mappings



21
22
23
# File 'lib/paraphrase/query.rb', line 21

def params
  @params
end

#sourceObject (readonly)

Returns the value of attribute source.



21
# File 'lib/paraphrase/query.rb', line 21

attr_reader :params, :source

Class Method Details

.inherited(klass) ⇒ Object

Set mappings on inheritance to ensure they're unique per subclass



24
25
26
# File 'lib/paraphrase/query.rb', line 24

def self.inherited(klass)
  klass.mappings = []
end

.map(name, options) ⇒ Object

Add a ScopeMapping instance to .mappings



31
32
33
34
35
36
37
# File 'lib/paraphrase/query.rb', line 31

def self.map(name, options)
  if mappings.map(&:method_name).include?(name)
    raise DuplicateScopeError, "scope :#{name} has already been added"
  end

  mappings << ScopeMapping.new(name, options)
end

Instance Method Details

#respond_to_missing?(name, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


72
73
74
# File 'lib/paraphrase/query.rb', line 72

def respond_to_missing?(name, include_private = false)
  super || results.respond_to?(name, include_private)
end

#resultsActiveRecord::Relation, Array

Loops through #mappings and apply scope methods to #source. If values are missing for a required key, an empty array is returned.

Returns:

  • (ActiveRecord::Relation, Array)


59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/paraphrase/query.rb', line 59

def results
  return @results if @results

  ActiveSupport::Notifications.instrument('query.paraphrase', :params => params, :source_name => source.name, :source => source) do
    @results = mappings.inject(source) do |query, scope|
      query = scope.chain(params, query)

      break [] if query.nil?
      query
    end
  end
end