Class: Plutonium::Resource::QueryObject
- Inherits:
-
Object
- Object
- Plutonium::Resource::QueryObject
- Defined in:
- lib/plutonium/resource/query_object.rb
Instance Attribute Summary collapse
-
#default_scope_name ⇒ Object
Returns the value of attribute default_scope_name.
-
#default_sort_config ⇒ Object
Returns the value of attribute default_sort_config.
-
#search_filter ⇒ Object
readonly
Returns the value of attribute search_filter.
-
#search_query ⇒ Object
readonly
Returns the value of attribute search_query.
Instance Method Summary collapse
-
#active_filter_descriptions ⇒ Object
Returns an array of hashes describing each currently active filter.
-
#all_scope_selected? ⇒ Boolean
Returns true if user explicitly selected “All” scope (no filtering).
-
#apply(scope, params, context: nil) ⇒ Object
Applies the defined filters and sorts to the given scope.
-
#build_url(**options) ⇒ String
Builds a URL with the given options for search and sorting.
-
#define_filter(name, body) ⇒ Object
Defines a filter with the given name and body.
-
#define_scope(name, body = nil, condition: nil) ⇒ Object
Defines a scope with the given name and body.
-
#define_search(body) ⇒ Object
Defines a search filter with the given body.
-
#define_sorter(name, body = nil, using: nil) ⇒ Object
Defines a sort with the given name and body.
- #filter_definitions ⇒ Object
-
#initialize(resource_class, params, request_path) {|_self| ... } ⇒ QueryObject
constructor
Initializes a QueryObject with the given resource_class and parameters.
- #scope_conditions ⇒ Object
- #scope_definitions ⇒ Object
-
#scope_visible?(name, view_context) ⇒ Boolean
Display-only visibility gate for a scope, mirroring condition: on actions.
-
#selected_scope ⇒ Object
Returns the currently selected scope (may be default if none explicitly selected).
- #sort_definitions ⇒ Object
-
#sort_params_for(name) ⇒ Hash?
Provides sorting parameters for the given field name.
Constructor Details
#initialize(resource_class, params, request_path) {|_self| ... } ⇒ QueryObject
Initializes a QueryObject with the given resource_class and parameters.
11 12 13 14 15 16 17 18 19 20 |
# File 'lib/plutonium/resource/query_object.rb', line 11 def initialize(resource_class, params, request_path, &) @resource_class = resource_class @params = params @request_path = request_path define_standard_queries yield self if block_given? extract_filter_params extract_sort_params end |
Instance Attribute Details
#default_scope_name ⇒ Object
Returns the value of attribute default_scope_name.
5 6 7 |
# File 'lib/plutonium/resource/query_object.rb', line 5 def default_scope_name @default_scope_name end |
#default_sort_config ⇒ Object
Returns the value of attribute default_sort_config.
5 6 7 |
# File 'lib/plutonium/resource/query_object.rb', line 5 def default_sort_config @default_sort_config end |
#search_filter ⇒ Object (readonly)
Returns the value of attribute search_filter.
4 5 6 |
# File 'lib/plutonium/resource/query_object.rb', line 4 def search_filter @search_filter end |
#search_query ⇒ Object (readonly)
Returns the value of attribute search_query.
4 5 6 |
# File 'lib/plutonium/resource/query_object.rb', line 4 def search_query @search_query end |
Instance Method Details
#active_filter_descriptions ⇒ Object
Returns an array of hashes describing each currently active filter. Each hash has: name, label, value_label, clear_url
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/plutonium/resource/query_object.rb', line 145 def active_filter_descriptions filter_definitions.filter_map do |name, filter| name = name.to_sym filter_params = params[name] next unless filter_params.present? value_label = case filter_params when Hash, ActionController::Parameters entries = filter_params.to_h.reject { |_, v| v.blank? } next if entries.empty? # Single-input filters defer to the filter's `humanize_value` # (e.g. Association resolves ids to labels, Boolean translates # "true" -> "Yes"). Multi-input filters keep input-name # qualifiers (e.g. "from 2024, to 2025"). if entries.size == 1 humanized = filter.humanize_value(entries.values.first) next if humanized.blank? humanized else entries.map { |k, v| "#{k.to_s.humanize.downcase} #{v}" }.join(", ") end when Array entries = filter_params.reject(&:blank?) next if entries.empty? humanized = filter.humanize_value(entries) next if humanized.blank? humanized else next if filter_params.to_s.blank? humanized = filter.humanize_value(filter_params) next if humanized.blank? humanized end { name: name, label: name.to_s.humanize, value_label: value_label, clear_url: build_url(name => nil) } end end |
#all_scope_selected? ⇒ Boolean
Returns true if user explicitly selected “All” scope (no filtering)
134 |
# File 'lib/plutonium/resource/query_object.rb', line 134 def all_scope_selected? = @all_scope_selected |
#apply(scope, params, context: nil) ⇒ Object
Applies the defined filters and sorts to the given scope.
111 112 113 114 115 116 117 118 119 |
# File 'lib/plutonium/resource/query_object.rb', line 111 def apply(scope, params, context: nil) params = deep_compact(params.with_indifferent_access) scope = search_filter.apply(scope, search: params[:search]) if search_filter && params[:search] # Use selected_scope which includes the default when no explicit selection effective_scope = @selected_scope_filter scope = scope_definitions[effective_scope].apply(scope, context:) if effective_scope && scope_definitions[effective_scope] scope = apply_sorts(scope, params) apply_filters(scope, params) end |
#build_url(**options) ⇒ String
Builds a URL with the given options for search and sorting.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/plutonium/resource/query_object.rb', line 70 def build_url(**) q = {} q[:search] = .key?(:search) ? [:search].presence : search_query q[:scope] = if .key?(:scope) [:scope].presence else selected_scope_filter end if .delete(:replace) q[:sort_directions] = {} q[:sort_fields] = [] else q[:sort_directions] = selected_sort_directions.dup q[:sort_fields] = selected_sort_fields.dup end (q, ) filter_keys = filter_definitions.keys.map(&:to_sym) filter_overrides = .slice(*filter_keys).stringify_keys q.merge! params.with_indifferent_access.slice(*filter_definitions.keys) q.merge!(filter_overrides) compacted = deep_compact({q: q}) # Preserve explicit "All" selection (scope: nil in options means show all) if .key?(:scope) && [:scope].nil? compacted[:q] ||= {} compacted[:q][:scope] = "" end query_params = compacted.to_param "#{@request_path}?#{query_params}" end |
#define_filter(name, body) ⇒ Object
Defines a filter with the given name and body.
26 27 28 |
# File 'lib/plutonium/resource/query_object.rb', line 26 def define_filter(name, body, &) filter_definitions[name] = build_query(body, &) end |
#define_scope(name, body = nil, condition: nil) ⇒ Object
Defines a scope with the given name and body.
35 36 37 38 39 |
# File 'lib/plutonium/resource/query_object.rb', line 35 def define_scope(name, body = nil, condition: nil, **) body ||= name scope_definitions[name] = build_query(body) scope_conditions[name] = condition if condition end |
#define_search(body) ⇒ Object
Defines a search filter with the given body.
59 60 61 62 63 |
# File 'lib/plutonium/resource/query_object.rb', line 59 def define_search(body) @search_filter = build_query(body) do |query| query.input :search end end |
#define_sorter(name, body = nil, using: nil) ⇒ Object
Defines a sort with the given name and body.
45 46 47 48 49 50 51 52 53 54 |
# File 'lib/plutonium/resource/query_object.rb', line 45 def define_sorter(name, body = nil, using: nil) if body.nil? sort_field = using || determine_sort_field(name) body = ->(scope, direction:) { scope.order(sort_field => direction) } end sort_definitions[name] = build_query(body) do |query| query.input :direction end end |
#filter_definitions ⇒ Object
139 |
# File 'lib/plutonium/resource/query_object.rb', line 139 def filter_definitions = @filter_definitions ||= {}.with_indifferent_access |
#scope_conditions ⇒ Object
123 |
# File 'lib/plutonium/resource/query_object.rb', line 123 def scope_conditions = @scope_conditions ||= {}.with_indifferent_access |
#scope_definitions ⇒ Object
121 |
# File 'lib/plutonium/resource/query_object.rb', line 121 def scope_definitions = @scope_definitions ||= {}.with_indifferent_access |
#scope_visible?(name, view_context) ⇒ Boolean
Display-only visibility gate for a scope, mirroring condition: on actions. Returns true when no condition is set.
127 128 129 130 131 |
# File 'lib/plutonium/resource/query_object.rb', line 127 def scope_visible?(name, view_context) condition = scope_conditions[name] return true if condition.nil? Plutonium::Action::ConditionContext.new(view_context, nil).instance_exec(&condition) end |
#selected_scope ⇒ Object
Returns the currently selected scope (may be default if none explicitly selected)
137 |
# File 'lib/plutonium/resource/query_object.rb', line 137 def selected_scope = @selected_scope_filter |
#sort_definitions ⇒ Object
141 |
# File 'lib/plutonium/resource/query_object.rb', line 141 def sort_definitions = @sort_definitions ||= {}.with_indifferent_access |
#sort_params_for(name) ⇒ Hash?
Provides sorting parameters for the given field name.
192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/plutonium/resource/query_object.rb', line 192 def sort_params_for(name) return unless sort_definitions[name] multi = selected_sort_fields.size > 1 && selected_sort_fields.include?(name.to_s) { url: build_url(sort: name, replace: true), multi_url: build_url(sort: name), reset_url: build_url(sort: name, reset: true), position: selected_sort_fields.index(name.to_s), direction: selected_sort_directions[name], multi: multi } end |