Skip to content

Instantly share code, notes, and snippets.

@ssnickolay
Last active September 27, 2019 10:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ssnickolay/b4125546e3ead945ae9ac8fb2130b042 to your computer and use it in GitHub Desktop.
Save ssnickolay/b4125546e3ead945ae9ac8fb2130b042 to your computer and use it in GitHub Desktop.
Query Object with Active Record
class Filters
class Base
attr_reader :scope
def initialize(scope)
@scope = scope
end
end
class ByPrice < Base
def call(price:, **_options)
return scope if price.nil?
scope.where(price: price)
end
end
class ByName
def call(name:, **_options)
return scope if name.nil?
scope.where('name ILIKE ?', "%#{name}%")
end
end
class Paginate
PER_PAGE = 10
def call(page:, per_page: PER_PAGE, **_options)
# default kaminari methods
scope.page(page).per(per_page)
end
end
class OrderBy
def call(order_by:, order_direction:, **_options)
scope.order(order_by => order_direction)
end
end
end
class ProductFilter
# params
# => { price: 100_000, name: 'Apple', page: 2, order_by: created_at, order_direction: :asc }
def call(params)
[
Filters::ByPrice,
Filters::ByName,
Filters::OrderBy,
Filters::Paginate
].inject(Product.all) { |scope, klass| scope = klass.new(scope).call(params) }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment