Class: CrudComponents::Query
- Inherits:
-
Object
- Object
- CrudComponents::Query
- Defined in:
- lib/crud_components/query.rb
Overview
Applies URL params to a relation: filtering, global search, sorting.
The uniform rule: a param is applied iff it names a filterable field of the fieldset in play that the current user may see (or one of the reserved params q/sort/dir/page/per). Everything else never reaches SQL.
Constant Summary collapse
- SORT_DIRECTIONS =
%w[asc desc].freeze
- RESERVED_PARAMS =
The reserved params the query itself reads. Pagination (page/per) is the host's — it lives in the controller, never here — so it is not listed.
%w[q sort dir].freeze
Instance Attribute Summary collapse
-
#fieldset ⇒ Object
readonly
Returns the value of attribute fieldset.
-
#model ⇒ Object
readonly
Returns the value of attribute model.
-
#param_prefix ⇒ Object
readonly
Returns the value of attribute param_prefix.
-
#structure ⇒ Object
readonly
Returns the value of attribute structure.
Instance Method Summary collapse
- #active? ⇒ Boolean
-
#active_filters ⇒ Object
The active filter and search values keyed by their logical (unprefixed) name — for rendering active-filter chips.
- #apply(scope) ⇒ Object
- #fieldset_name ⇒ Object
- #filter_fields ⇒ Object
-
#filter_params ⇒ Object
The subset of the current request params this query reads, present values only, keyed by their real (prefixed) param names.
-
#initialize(model, params, fieldset: nil, ability: nil, param_prefix: nil, extra_fields: []) ⇒ Query
constructor
A new instance of Query.
- #param_name(key) ⇒ Object
-
#permitted_keys ⇒ Object
The (prefixed) request-param names this query reads: every visible filter field's value and
_geq/_leqbounds, plus the reserved q/sort/dir. - #searchable? ⇒ Boolean
-
#sort_state ⇒ Object
[field_name_string, direction_string] or nil.
- #sortable_fields ⇒ Object
-
#value(key) ⇒ Object
Current value of a (logical, unprefixed) param — for filter controls.
Constructor Details
#initialize(model, params, fieldset: nil, ability: nil, param_prefix: nil, extra_fields: []) ⇒ Query
Returns a new instance of Query.
16 17 18 19 20 21 22 23 24 |
# File 'lib/crud_components/query.rb', line 16 def initialize(model, params, fieldset: nil, ability: nil, param_prefix: nil, extra_fields: []) @model = model @structure = Structure.for(model) @fieldset = fieldset.is_a?(Fieldset) ? fieldset : @structure.fieldset(fieldset) @params = extract(params) @permission = PermissionContext.new(ability) @param_prefix = param_prefix @extra_fields = extra_fields end |
Instance Attribute Details
#fieldset ⇒ Object (readonly)
Returns the value of attribute fieldset.
14 15 16 |
# File 'lib/crud_components/query.rb', line 14 def fieldset @fieldset end |
#model ⇒ Object (readonly)
Returns the value of attribute model.
14 15 16 |
# File 'lib/crud_components/query.rb', line 14 def model @model end |
#param_prefix ⇒ Object (readonly)
Returns the value of attribute param_prefix.
14 15 16 |
# File 'lib/crud_components/query.rb', line 14 def param_prefix @param_prefix end |
#structure ⇒ Object (readonly)
Returns the value of attribute structure.
14 15 16 |
# File 'lib/crud_components/query.rb', line 14 def structure @structure end |
Instance Method Details
#active? ⇒ Boolean
79 |
# File 'lib/crud_components/query.rb', line 79 def active? = active_filters.any? |
#active_filters ⇒ Object
The active filter and search values keyed by their logical (unprefixed)
name — for rendering active-filter chips. Range bounds appear as
<field>_geq / <field>_leq; the search box as q.
72 73 74 75 76 77 |
# File 'lib/crud_components/query.rb', line 72 def active_filters (filter_param_keys + ['q']).each_with_object({}) do |key, active| val = param(key) active[key] = val if val end end |
#apply(scope) ⇒ Object
26 27 28 29 30 |
# File 'lib/crud_components/query.rb', line 26 def apply(scope) scope = apply_filters(scope) scope = apply_search(scope) apply_sort(scope) end |
#fieldset_name ⇒ Object
32 |
# File 'lib/crud_components/query.rb', line 32 def fieldset_name = fieldset.name |
#filter_fields ⇒ Object
34 35 36 37 |
# File 'lib/crud_components/query.rb', line 34 def filter_fields (structure.fieldset_filter_fields(fieldset) + @extra_fields.select(&:filterable?)) .select { |f| f.permitted?(@permission) } end |
#filter_params ⇒ Object
The subset of the current request params this query reads, present values only, keyed by their real (prefixed) param names. Feed it to filter-preserving links (pagers, breadcrumbs, "reset" targets) instead of keeping a hand-maintained copy of the params.
62 63 64 65 66 67 |
# File 'lib/crud_components/query.rb', line 62 def filter_params permitted_keys.each_with_object({}) do |key, kept| raw = @params[key] kept[key] = raw if raw.is_a?(String) && raw.present? end end |
#param_name(key) ⇒ Object
87 |
# File 'lib/crud_components/query.rb', line 87 def param_name(key) = "#{prefix}#{key}" |
#permitted_keys ⇒ Object
The (prefixed) request-param names this query reads: every visible filter
field's value and _geq/_leq bounds, plus the reserved q/sort/dir. The
single source of truth for a strong-params permit list, so it can't drift
from the columns:
params.permit(*query.permitted_keys)
54 55 56 |
# File 'lib/crud_components/query.rb', line 54 def permitted_keys (filter_param_keys + RESERVED_PARAMS).map { |key| param_name(key) } end |
#searchable? ⇒ Boolean
44 |
# File 'lib/crud_components/query.rb', line 44 def searchable? = structure.searchable? |
#sort_state ⇒ Object
[field_name_string, direction_string] or nil.
82 83 84 85 |
# File 'lib/crud_components/query.rb', line 82 def sort_state field = current_sort_field field && [field.name.to_s, direction] end |
#sortable_fields ⇒ Object
39 40 41 42 |
# File 'lib/crud_components/query.rb', line 39 def sortable_fields (structure.fieldset_sortable_fields(fieldset) + @extra_fields.select(&:sortable?)) .select { |f| f.permitted?(@permission) } end |
#value(key) ⇒ Object
Current value of a (logical, unprefixed) param — for filter controls.
47 |
# File 'lib/crud_components/query.rb', line 47 def value(key) = param(key) |