parascope gem for param-based scope generation
defaults
method. This allows to have default params with dynamic values, such as time- or params-based. Examples:class MyQuery < Parascope::Query
defaults page: 1, per_page: 10
sifter :fresh do
defaults { {later_than: 1.day.ago} }
end
# it is also possible to pass static defaults and block at the same time:
sifter :old do
defaults per_page: 20 do
{older_than: 1.week.ago}
end
end
end
Query.raise_on_guard_violation(value)
option with default value of true
(to persist current behavior). When set to false
, instead of raising an exception, query scope will be resolved to nil
, and query instance will have violation
property set with the value of first violated block error message"guard block violated on ./some_query.rb:3"
. Example:class UsersQuery < Parascope::Query
raise_on_guard_violation false
# ...
sift_by(:sort_col, :sort_dir) do |scol, sdir|
guard(':sort_dir should be "asc" or "desc"') do
sdir.downcase.in?(%w(asc desc))
end
base_scope { |scope| scope.order(scol => sdir) }
end
end
query = UsersQuery.new(sort_col: 'id', sort_dir: 'there')
query.resolved_scope # => nil
query.violation # => ":sort_dir should be \"asc\" or \"desc\""
base_dataset
is an alias for base_scope
dataset
is an alias for scope
resolved_dataset
and resolve
are both aliases for resolved_scope
:index
option now accepts :first
and :last
values. This comes in handy when you have a base Query
class with a query that you want to ensure will be applied last. I.e. something like:query_by(:page, :per_page, index: :last) do |page, per_page|
scope.paginate(page, per_page)
end
query_by!(*fields)
and sift_by!(*fields)
methods. Unlike their non-bang counterparts, they don't check for presence of values under fields
keys in params
and will execute declared block in any case, yielding values to it, whatever they are. Note that :if
and :unless
options still can be used to omit block execution based on specified conditions.base_scope
blocks are not applied on explicitly passed scope was erroneously considered as a bug and "fixed" in version 1.0.1
. But in fact, one can always (and should) use unoptional query
blocks in sifter definition to fully replace base_scope
functionality when initializing query objects with explicit scope, like so:class UserQuery < Parascope::Query
sifter :with_projects do
query { scope.joins(:projects) }
# ...
end
end
query = UserQuery.new(params, scope: some_users)
base_scope
application on sifted queries that were initialized with explicit scope, i.e. having the following:class MyQuery < Parascope::Query
sifter(:foo) do
base_scope { |scope| scope.foo }
end
end
# ...
query = MyQuery.new({foo: true}, scope: some_scope)
it is expected that query.resolved_scope
would be some_scope.foo
. This is now true.
master
branch, but not released as separate gem version.Forwardable
has been removed from Parascope::Query
. You can now safely use convenient ActiveSupport
's delegate
method in Query classes.UndefinedScopeError
and GuardViolationError
has been moved from Parascope::Query
to Parascope
module itself.UnpermittedError
alias has been removed.Parascope::Query.build
method to initialize a query object with empty params. So you can now do something like UsersQuery.build(company: company)
instead of UsersQuery.new({}, company: company)
query_spec.rb
query { scope.active }
query(if: :active?) { scope.active }
. Supported options - :if
, :unless
. Supported values - String
, Symbol
(designate name of method to be called), Proc
(executed in context of query), arbitrary value (accepted as is).resolved_scope
accepts also a list of keys that should be evaluated to true
in params. I.e. resolved_scope(:paginated)
is the same as resolved_scope(paginated: true)
. Useful in conjunction with sifter(:sifter_name)
blocks.query
is an alias for query_by
, sifter
is an alias for sift_by
.GuardViolationError
. UnpermittedError
left as an alias, but will be removed in future.