class Paraphrase::Query
Attributes
@!attribute [r] params
@return [HashWithIndifferentAccess] filtered parameters based on keys defined in `mappings`
@!attribute [r] result
@return [ActiveRecord::Relation] resulting {ActiveRecord::Relation} instance from queries
@!attribute [r] params
@return [HashWithIndifferentAccess] filtered parameters based on keys defined in `mappings`
@!attribute [r] result
@return [ActiveRecord::Relation] resulting {ActiveRecord::Relation} instance from queries
Public Class Methods
Set `mappings` on inheritance to ensure they're unique per subclass
# File lib/paraphrase/query.rb, line 30 def self.inherited(klass) klass.mappings = [] klass.source = klass.to_s.sub(/Query$/, '') klass.params_filter = Class.new(Paraphrase::ParamsFilter) klass.const_set(:ParamsFilter, klass.params_filter) klass.repository = Class.new(Paraphrase::Repository) klass.const_set(:Repository, klass.repository) end
Keys mapped to scopes
@return [Array<Symbol>]
# File lib/paraphrase/query.rb, line 44 def self.keys mappings.flat_map(&:keys) end
Add a {Mapping} instance to {Query#mappings}. Defines a reader for each key to read from {Query#params}.
@overload map(*keys, options)
Maps a key to a scope @param [Array<Symbol>] keys query params to be mapped to the scope @param [Hash] options options to configure {Mapping Mapping} instance @option options [Symbol, Array<Symbol>] :to scope to map query params to @option options [true, Symbol, Array<Symbol>] :whitelist lists all or a subset of param keys as optional
# File lib/paraphrase/query.rb, line 58 def self.map(*keys) options = keys.extract_options! scope_name = options[:to] if mappings.any? { |mapping| mapping.name == scope_name } raise DuplicateMappingError.new(scope_name) end mappings << Mapping.new(keys, options) keys.each do |key| define_method(key) { params[key] } params_filter.class_eval do define_method(key) { params[key] } end end end
Filters out parameters irrelevant to the query and sets the base scope for to begin the chain.
@param [Hash] query_params query parameters @param [ActiveRecord::Relation] relation relation object to apply methods to
# File lib/paraphrase/query.rb, line 103 def initialize(query_params, relation = nil) @params = filter_params(query_params || {}) @result = mappings.inject(relation || default_relation) do |result, mapping| repository.chain(result, mapping, @params) end end
Define a method on `ParamsFilter` to process the raw value of the query param
@param [Symbol] query_param query param to process @param [Proc] block block to process the specified `query_param`
# File lib/paraphrase/query.rb, line 82 def self.param(query_param, &block) params_filter.class_eval do define_method(query_param, &block) end end
Define a scope on `Repository`
@param [Symbol] scope_name name of the scope specified in {Query.map} @param [Proc] block body of the scope to be defined
# File lib/paraphrase/query.rb, line 92 def self.scope(scope_name, &block) repository.class_eval do define_method(scope_name, &block) end end
Public Instance Methods
Look up a `params` value
@param [String,Symbol] key key to read
# File lib/paraphrase/query.rb, line 114 def [](key) unless keys.include?(key.to_sym) raise UndefinedKeyError.new(key, keys) end params[key] end
Return an `ActiveRecord::Relation` corresponding to the source class determined from the `source` class attribute that defaults to the name of the class.
@return [ActiveRecord::Relation]
# File lib/paraphrase/query.rb, line 127 def default_relation klass = self.class.source.to_s.constantize klass.default_paraphrase_relation end
@see Query.keys
# File lib/paraphrase/query.rb, line 133 def keys self.class.keys end
Private Instance Methods
# File lib/paraphrase/query.rb, line 139 def filter_params(params) params_filter.new(params, keys).result end