class Right::Fetcher

Configure your own fetcher

PagesFetcher < Right::Fetcher
  self.resource_class = Page
end

You can configure filterable attributes for model

filter :id, validates: { presence: true }
filter :name
filter :start_at, validates: { presence: true }

If your property name doesn't match the name in the query string, use the :as option:

filter :kind, as: :type

So the Movie#kind property would be exposed to API as :type

You may specify allowed sorting order:

sort :id
sort :name

If your property name doesn't match the name in the query string, use the :as option:

sort :position, as: :relevance

So client should pass +?sort=relevance+ in order to sort by position

It's also possible to reverse meaning of the order direction. For example it's not make sense to order by position from lower value to higher. The meaning default for that sorting is reversed order by default, so more relevant elenents would be the first.

sort :position, as: :relevance, reverse_direction: true

Attributes

params[R]

@return [Hash]

Public Class Methods

new(params) click to toggle source

@param params [Hash]

# File lib/right/fetcher.rb, line 55
def initialize(params)
  @params = params
end

Private Class Methods

after(&block) click to toggle source

Add middleware to the end of middleware chane

class MovieFetcher
  after do |scope, params|
    # do something with scope and params
    [scope.map(&:resource), params]
  end
end
# File lib/right/fetcher.rb, line 215
def after(&block)
  alter_middleware(:use, &block)
end
alter_middleware(method_name, *args) { |*env| ... } click to toggle source
# File lib/right/fetcher.rb, line 234
def alter_middleware(method_name, *args)
  fail ArgumentError unless block_given?
  middleware_changes.push lambda { |builder|
    builder.send method_name, *args, lambda { |env|
      yield(*env).tap do |r|
        if !r.is_a?(Array) || r.size != 2
          fail 'After block must return tuple of scope and params'
        end
      end
    }
  }
end
before(middleware_or_index = 0, &block) click to toggle source

Add middleware to the beginning of middleware chane

class MovieFetcher
  before do |scope, params|
    # do something with scope and params
    [scope.map(&:resource), params]
  end
end
# File lib/right/fetcher.rb, line 228
def before(middleware_or_index = 0, &block)
  alter_middleware(:insert_before, middleware_or_index, &block)
end
filter(*args) click to toggle source

Register collection filter by its name @see Right::Filter for details

@overload filter(filter_name, options)

@param [Symbol] filter_name
@param [Hash] options
@return [void]

@example

filter :genre_name, on: :resource

@overload filter(filter_name: predicates, **options)

@param [Symbol] filter_name
@param [<Symbol>] predicates
@param [Hash] other options options
@return [void]

@example

filter genre_name: [:eq, :in], on: :resource
# File lib/right/fetcher.rb, line 186
def filter(*args)
  options = args.extract_options!
  if args.empty?
    filter_name = options.keys.first
    predicates = options.values.first
    options = options.except(filter_name).merge(predicates: predicates)
  else
    filter_name = args.first
  end

  definition = FilterParameterDefinition.new(filter_name, options)
  filter_parameters_definition.add(definition)
end
middleware(&change) click to toggle source

Alter middleware chain with the given block @param [Proc] change @return [Right]

@example

class ChannelsFetcher
  middleware do
    use CustomMiddleware
  end
end
# File lib/right/fetcher.rb, line 152
def middleware(&change)
  fail ArgumentError unless block_given?
  middleware_changes << change
  self
end
run(params, &block) click to toggle source

@param params [Hash] user provided input @yieldparam collection [ActiveRecord::Relation]

# File lib/right/fetcher.rb, line 202
def run(params, &block)
  new(params).call(&block)
end
sort(name, options = {}) click to toggle source

Register collection sorting by its name @param name [Symbol] of the field @return [void] @see RansackableSort for details

# File lib/right/fetcher.rb, line 163
def sort(name, options = {})
  definition = SortParameterDefinition.new(name, options)
  sort_parameters_definition.add(definition)
end

Public Instance Methods

call() { |result| ... } click to toggle source

@return [Right::Result] filtered and sorted collection @yieldparam collection [Result] if a block given

@example

PagesFetcher.new(params).call #=> Result

@example block syntax

PagesFetcher.new(params) do |result|
  if result.success?
    result.get
  else
    result.errors
  end
end
# File lib/right/fetcher.rb, line 74
def call
  processed_params, errors = process_params(params)
  result = if errors.any?
             Failure.new(errors)
           else
             Success.new(fetch(processed_params))
           end

  if block_given?
    yield result
  else
    result
  end
end

Private Instance Methods

fetch(parsed_params) click to toggle source

@param parsed_params [Hash] @return [ActiveRecord::Relation] @api public This method may be overridden to implement integration with library other than Ransack

# File lib/right/fetcher.rb, line 96
def fetch(parsed_params)
  collection, = middleware.call([self.class.resource_class, parsed_params])
  collection
end
fetch_middleware() click to toggle source

Library middleware stack @return [Middleware::Builder]

# File lib/right/fetcher.rb, line 122
def fetch_middleware
  Middleware::Builder.new do |b|
    b.use FilterMiddleware
    b.use SortMiddleware
    b.use PaginationMiddleware
  end
end
middleware() click to toggle source

User modified middleware stack @return [Middleware::Builder]

# File lib/right/fetcher.rb, line 132
def middleware
  fetch_middleware.tap do |builder|
    self.class.middleware_changes.each do |change|
      builder.instance_eval(&change)
    end
  end
end
process_params(params) click to toggle source

@return [Hash, Array] tuple of parameters and processing errors

this errors may be shown to front-end developer

@api public

# File lib/right/fetcher.rb, line 104
def process_params(params)
  process_params_middleware.call([params, []])
end
process_params_middleware() click to toggle source

Library params processing middleware stack @return [Middleware::Builder]

# File lib/right/fetcher.rb, line 110
def process_params_middleware
  Middleware::Builder.new do |b|
    b.use FilterParametersExtractor, self.class.filter_parameters_definition
    b.use FilterParametersValidator
    b.use SortParametersExtractor, self.class.sort_parameters_definition
    b.use SortParametersValidator
    b.use PaginationParametersValidator
  end
end