active_queryable 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5bf4db93e62b6ef9584ed59ac624d983debc4a7792dc4debc252fe4958c0e3ac
4
- data.tar.gz: 38bd3b1e7b4e9138be78e1cfed968b9dc499894c5d6aa5d1710bf5d1aa032d26
3
+ metadata.gz: ca76d46d098d260a1f59a1fd6e50d59cbab69eb95ba87f25470ccb08aa3050f2
4
+ data.tar.gz: 9562f2b4d7a4cce6ba1ba6bb070c6e6d9cf031d6205bf1006e5b5c1f21566ed4
5
5
  SHA512:
6
- metadata.gz: fe31f1bacbd161809ede6ad71b12793f1515a4b189b59006b5558ef7d4b9cdd5c43bb905bd2e932d8d087f15e014efce399c7ce13631277265522e9fb3c6a589
7
- data.tar.gz: 4f0b563933703484579689cee4fbabe5445ad021115c73bc863f76f9db3ee61df511fa29bd9041aabb81ffbfa1020215005a916cf6de0cc6e4905573c209d2f6
6
+ metadata.gz: 5ec24780124afa2fd02e2d6bdf9a4f54f6dd980c8852adc43c4ae37144f887d54eccbdebf5e8d50765b3cc3e051762f4c1e62f7006a3a5385d5ed6962e3ce22f
7
+ data.tar.gz: aaf987e005a9f87b39ae00f63adaf7791a11b0facc962ae2f9b70e541e74f7b0281e1d71e6428ba71b97c7ba924dd20cf08b126e960430f9ecf8ef88d0ec9d0d
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveQueryable
2
- VERSION = '0.3.0'
4
+ # @return [String] the version of the gem
5
+ VERSION = '0.3.1'
3
6
  end
@@ -1,12 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_support/concern'
4
+ require 'active_record'
4
5
  require 'kaminari/activerecord'
5
6
 
7
+ # A light and simple gem for sorting / filtering / paginating a model in Rails.
6
8
  module ActiveQueryable
7
- extend ActiveSupport::Concern
9
+ extend ActiveSupport::Concern
8
10
 
9
- QUERYABLE_VALID_PARAMS = [:filter, :sort, :page, :per].freeze
11
+ # @private
12
+ QUERYABLE_VALID_PARAMS = %i[filter sort page per].freeze
10
13
 
11
14
  included do
12
15
  class_attribute :_queryable_default_order
@@ -14,34 +17,94 @@ module ActiveQueryable
14
17
  class_attribute :_queryable_default_per
15
18
  class_attribute :_queryable_filter_keys
16
19
  class_attribute :_queryable_expandable_filter_keys
17
- end
20
+ end
18
21
 
19
- module Initializer
22
+ # @private
23
+ module Initializer
24
+ # Enables ActiveQueryable for the model
25
+ # @example
26
+ # class User < ApplicationRecord
27
+ # as_queryable
28
+ # end
29
+ #
30
+ # @!parse include ActiveQueryable
31
+ # @return [void]
20
32
  def as_queryable
21
- send :include, ActiveQueryable
22
- end
23
- end
33
+ send :include, ActiveQueryable
34
+ end
35
+ end
24
36
 
37
+ # Extension methods for ActiveRecord::Base
38
+ # @!method query_by(params)
39
+ # Runs a query with the given params
40
+ # @example
41
+ # User.query_by(sort: '-name', filter: { name: 'John' })
42
+ # @param params [Hash,ActionController::Parameters]
43
+ # @option params [String] :sort
44
+ # @option params [Hash] :filter
45
+ # @option params [String] :page
46
+ # @option params [String] :per
47
+ # @option params [Hash] :page
48
+ # @return [ActiveRecord::Relation]
49
+ # @!method of_not(ids)
50
+ # @example
51
+ # User.of_not([1, 2, 3]) # => equivalent of: User.where.not(id: [1, 2, 3])
52
+ # Returns a scope with the given ids excluded
53
+ # @param ids [Array<Integer,String>]
54
+ # @return [ActiveRecord::Relation]
25
55
  module ClassMethods
56
+ # Configures the model to be queryable
57
+ # @example
58
+ # class User < ApplicationRecord
59
+ # as_queryable
60
+ # queryable order: { name: :asc }, page: 1, per: 25, filter: %i[name email]
61
+ # end
62
+ #
63
+ # @param options [Hash]
64
+ # @option options [Hash<Symbol,Symbol>] :order { id: :asc }
65
+ # @option options [Integer] :page 1
66
+ # @option options [Integer] :per 25
67
+ # @option options [Array<Symbol,String>] :filter []
68
+ # @return [void]
26
69
  def queryable(options)
27
- self._queryable_default_order = options[:order] || { id: :asc }
28
- self._queryable_default_page = options[:page] || 1
29
- self._queryable_default_per = options[:per] || 25
30
- self._queryable_filter_keys = (((options[:filter] || [])).map(&:to_sym))
70
+ queryable_configure_options(options)
31
71
 
32
72
  scope :query_by, ->(params) { queryable_scope(params) }
33
73
  scope :of_not, ->(ids) { where.not(id: ids) }
34
74
  end
35
75
 
76
+ # A method to expand the filterable keys, useful to allow class inheritance
77
+ # @example
78
+ # class BaseItem < ApplicationRecord
79
+ # as_queryable
80
+ # queryable order: { name: :asc }, page: 1, per: 25, filter: %i[name email]
81
+ # end
82
+ # class AdvancedItem < BaseItem
83
+ # expand_queryable filter: %i[phone]
84
+ # end
85
+ #
86
+ #
87
+ # @param options [Hash]
88
+ # @option options [Array<Symbol,String>] :filter []
89
+ # @return [void]
36
90
  def expand_queryable(options)
37
91
  self._queryable_expandable_filter_keys ||= []
38
- self._queryable_expandable_filter_keys += (((options[:filter] || [])).map(&:to_sym))
92
+ self._queryable_expandable_filter_keys += ((options[:filter] || [])).map(&:to_sym)
39
93
  end
40
94
 
95
+ # @param params [Hash,ActionController::Parameters]
96
+ # @option params [String] :sort
97
+ # @option params [Hash] :filter
98
+ # @option params [String] :page
99
+ # @option params [String] :per
100
+ # @option params [Hash] :page
101
+ # @return [ActiveRecord::Relation]
41
102
  def queryable_scope(params)
42
103
  params = params.to_unsafe_h if params.respond_to? :to_unsafe_h
43
104
  params = params.with_indifferent_access if params.respond_to?(:with_indifferent_access)
44
- params.each_key { |k| QUERYABLE_VALID_PARAMS.include?(k.to_sym) || Rails.logger.error("Invalid key #{k} in queryable") }
105
+ params.each_key do |k|
106
+ QUERYABLE_VALID_PARAMS.include?(k.to_sym) || Rails.logger.error("Invalid key #{k} in queryable")
107
+ end
45
108
 
46
109
  order_params = queryable_validate_order_params(params[:sort])
47
110
  query = queryable_parse_order_scope(order_params, self)
@@ -51,6 +114,26 @@ module ActiveQueryable
51
114
 
52
115
  private
53
116
 
117
+ # @option options [Hash<Symbol,Symbol>] :order { id: :asc }
118
+ # @option options [Integer] :page 1
119
+ # @option options [Integer] :per 25
120
+ # @option options [Array<Symbol,String>] :filter []
121
+ # @return [void]
122
+ def queryable_configure_options(options)
123
+ self._queryable_default_order = options[:order] || { id: :asc }
124
+ self._queryable_default_page = options[:page] || 1
125
+ self._queryable_default_per = options[:per] || 25
126
+ self._queryable_filter_keys = (((options[:filter] || [])).map(&:to_sym))
127
+ end
128
+
129
+ # @param params [Hash,ActionController::Parameters]
130
+ # @option params [String] :sort
131
+ # @option params [Hash] :filter
132
+ # @option params [String] :page
133
+ # @option params [String] :per
134
+ # @option params [Hash] :page
135
+ # @param query [ActiveRecord::Relation]
136
+ # @return [ActiveRecord::Relation]
54
137
  def queryable_filtered_scope(params, query)
55
138
  filter_params = queryable_validate_filter_params(params[:filter])
56
139
 
@@ -67,10 +150,17 @@ module ActiveQueryable
67
150
  scope
68
151
  end
69
152
 
153
+ # @param params [String,nil]
154
+ # @return [Hash]
70
155
  def queryable_validate_order_params(params)
71
156
  queryable_parse_order_params(params) || _queryable_default_order
72
157
  end
73
158
 
159
+ # @param params [Hash,ActionController::Parameters]
160
+ # @option params [String] :page
161
+ # @option params [String] :per
162
+ # @option params [Hash] :page
163
+ # @return [Hash]
74
164
  def queryable_validate_page_params(params)
75
165
  page_params = {}
76
166
  if params[:page].respond_to?(:dig)
@@ -83,16 +173,20 @@ module ActiveQueryable
83
173
  page_params
84
174
  end
85
175
 
176
+ # @param filter_params [Hash,ActionController::Parameters,nil]
177
+ # @return [Hash]
86
178
  def queryable_validate_filter_params(filter_params)
87
179
  return nil if filter_params.nil?
88
180
 
89
- filters = (((self._queryable_filter_keys || []) | (self._queryable_expandable_filter_keys || [])) + ['not']).map(&:to_sym)
181
+ filters = (((_queryable_filter_keys || []) | (self._queryable_expandable_filter_keys || [])) + ['not']).map(&:to_sym)
90
182
  unpermitted = filter_params.except(*filters)
91
183
  Rails.logger.warn("Unpermitted queryable parameters: #{unpermitted.keys.join(', ')}") if unpermitted.present?
92
184
 
93
185
  filter_params.slice(*filters)
94
186
  end
95
187
 
188
+ # @param params [String,nil]
189
+ # @return [Hash]
96
190
  def queryable_parse_order_params(params)
97
191
  return nil unless params.is_a? String
98
192
 
@@ -102,6 +196,9 @@ module ActiveQueryable
102
196
  end.to_h
103
197
  end
104
198
 
199
+ # @param params [Hash,ActionController::Parameters,nil]
200
+ # @param query [ActiveRecord::Relation]
201
+ # @return [ActiveRecord::Relation]
105
202
  def queryable_parse_order_scope(params, query)
106
203
  return query unless params
107
204
 
@@ -116,13 +213,15 @@ module ActiveQueryable
116
213
  end || query
117
214
  end
118
215
 
216
+ # @param params [Hash,ActionController::Parameters,nil]
217
+ # @param query [ActiveRecord::Relation]
218
+ # @return [ActiveRecord::Relation]
119
219
  def queryable_parse_filter_scope(params, query)
120
220
  return query unless params
121
221
 
122
222
  params.inject(query) do |current_query, (k, v)|
123
223
  scope = "of_#{k}"
124
224
 
125
-
126
225
  if current_query.respond_to?(scope, true)
127
226
  current_query.public_send(scope, v)
128
227
  else
@@ -132,4 +231,7 @@ module ActiveQueryable
132
231
  end
133
232
  end
134
233
  end
135
- ActiveRecord::Base.send :extend, ActiveQueryable::Initializer
234
+
235
+ # rubocop:disable Lint/SendWithMixinArgument
236
+ ActiveRecord::Base.send(:extend, ActiveQueryable::Initializer)
237
+ # rubocop:enable Lint/SendWithMixinArgument
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_queryable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mònade