Module: RailsStuff::SortScope
- Defined in:
- lib/rails_stuff/sort_scope.rb
Overview
Provides safe and flexible way to sort collections by user’s input. Uses ‘has_scope` gem.
Supports different input format, and limits requested fields to allowed subset.
Defined Under Namespace
Modules: InstanceMethods
Class Method Summary collapse
- .extended(base) ⇒ Object
-
.filter_param(val, params, allowed, default = nil) ⇒ Object
Filters value with whitelist of allowed fields to sort by.
Instance Method Summary collapse
-
#has_sort_scope(config = {}) ⇒ Object
Setups has_scope to order collection by allowed columns.
Class Method Details
.extended(base) ⇒ Object
63 64 65 66 67 68 |
# File 'lib/rails_stuff/sort_scope.rb', line 63 def extended(base) base.class_eval do include InstanceMethods helper_method :current_sort_scope if respond_to?(:helper_method) end end |
.filter_param(val, params, allowed, default = nil) ⇒ Object
Filters value with whitelist of allowed fields to sort by.
rubocop:disable CyclomaticComplexity, PerceivedComplexity, BlockNesting
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/rails_stuff/sort_scope.rb', line 73 def filter_param(val, params, allowed, default = nil) val ||= default unless val == default val = val.to_unsafe_h if val.is_a?(ActionController::Parameters) val = if val.is_a?(Hash) val.each_with_object({}) do |(key, dir), h| h[key] = (dir == 'desc' ? :desc : :asc) if allowed.include?(key) end else allowed.include?(val) ? val : default end end if val && !val.is_a?(Hash) val = {val => ParamsParser.parse_boolean(params[:sort_desc]) ? :desc : :asc} end val end |
Instance Method Details
#has_sort_scope(config = {}) ⇒ Object
Setups has_scope to order collection by allowed columns. Sort column is filtered by SortScope.filter_param method. Accepts params:
#### Options
-
‘by` - array of available fields to sort by,
-
‘default` - default sort expression,
-
‘only` - bypassed to `has_scope` to limit actions (default to `:index`),
-
‘order_method` - use custom method to sort instead of `.order`.
rubocop:disable ClassVars
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/rails_stuff/sort_scope.rb', line 30 def has_sort_scope(config = {}) @@_sort_scope_id ||= 0 default = config[:default] || :id default = default.is_a?(Hash) ? default.stringify_keys : default.to_s allowed = Array.wrap(config[:by]).map(&:to_s) only_actions = config.fetch(:only, :index) order_method = config.fetch(:order_method, :order) # Counter added into scope name to allow to define multiple scopes in same controller. has_scope("sort_#{@@_sort_scope_id += 1}", as: :sort, default: nil, allow_blank: true, only: only_actions, type: :any, ) do |c, scope, val| sort_args = SortScope.filter_param(val, c.params, allowed, default) c.instance_variable_set(:@current_sort_scope, sort_args) scope.public_send(order_method, sort_args) end end |