queryko 1.2.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2344233fdafe42b76d1fbcef79137fc5506b0cd363fc8419e039da3b89bf62b0
4
- data.tar.gz: f3675c95e31ef885e50309ccae71415e37895f75969db69d0546c27448aa7a55
3
+ metadata.gz: abb6e5b750a802a5aa0838bca55feed2fc57fd0fa2b5e4ffe5d8bdd15d226079
4
+ data.tar.gz: 4dd022ad40ac529ad3b5b9303bf8e20013bebeb70810738f7958b89076a11b25
5
5
  SHA512:
6
- metadata.gz: b8bcabb4606be9cb25ada2e95819276b766e926fb6024d7c945d4189ad94e99fd6183b6377c6f73fb1050dc53218f949beb3e343b7482f379e47d96ffe6589fb
7
- data.tar.gz: 8b38c51f4e7950f4131625259290ef7f78b3123bbaf9498a18fbb55302e584a0df20896261542054a2ab287ac35beb9f74108584df64192aea09f8ce4a551b75
6
+ metadata.gz: b5691585e6b1885c7ffb23138f996c77aad1f6fffc6c76ba8136c9458c80db18ddf0a9f94044f4a288be0e343dc7670b2dcabeb1fc9a317d82e1b4b9a84db3d4
7
+ data.tar.gz: 70d4ed989265d73ad5310727251cb1df113bd81facb5cbee091bed6a5a7b38b416650b1506d87adadb2d8a2e41065d4e210bf47b958fc73422bc90628944d9e9
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- queryko (1.2.3)
4
+ queryko (1.2.2)
5
5
  activerecord (>= 4.0)
6
6
  activesupport (>= 4.0)
7
7
 
@@ -27,6 +27,7 @@ GEM
27
27
  tzinfo (~> 1.1)
28
28
  arel (9.0.0)
29
29
  builder (3.2.3)
30
+ byebug (11.0.1)
30
31
  concurrent-ruby (1.1.3)
31
32
  crass (1.0.4)
32
33
  diff-lcs (1.3)
@@ -82,6 +83,7 @@ PLATFORMS
82
83
 
83
84
  DEPENDENCIES
84
85
  bundler (~> 1.16)
86
+ byebug
85
87
  kaminari
86
88
  queryko!
87
89
  rake (~> 10.0)
data/README.md CHANGED
@@ -3,6 +3,7 @@
3
3
  This gem provides additional functionality on your query objects. It will filter and paginate your query by supplying arguments directly from controller params
4
4
 
5
5
  ## Installation
6
+
6
7
  ```ruby
7
8
  # Pagination
8
9
  gem 'kaminari'
@@ -22,33 +23,40 @@ Or install it yourself as:
22
23
  $ gem install queryko
23
24
 
24
25
  ## Usage
26
+
25
27
  ### Create a query object
28
+
26
29
  ``` ruby
27
30
  class ProductsQuery < Queryko::QueryObject
28
- add_range_attributes :created_at, :price
29
- add_searchables :name, :vendor
30
-
31
- table_name 'my_products' # optional
32
-
33
- def initialize params={}, relation = Product.all
34
- super(params, relation)
35
- end
31
+ feature :created_at, :min
32
+ feature :created_at, :max
33
+ feature :price, :min
34
+ feature :price, :max
35
+ feature :name, :search, as: :name
36
+ feature :vendor, :search, as: :vendor
37
+ feature :id, :after, as: :since_id
38
+ feature :id, :batch, as: :by_ids
36
39
  end
37
40
  ```
38
41
 
39
42
  ### Using your query object
40
- Filter your query by appending `_min` or `_max` on your defined attributes. You can also filter searc3h by attribute.
41
- As long as you defined it in your query object definition.
43
+ Filter your query by appending `_min` or `_max` on your defined attributes. You can also filter results by attribute with your defined feature.
44
+
42
45
  ``` ruby
43
46
  # Collection
44
47
  products = ProductsQuery.new(price_min: 100, price_max: 150, name: 'Milk').call
45
48
  products = ProductsQuery.new(since_id: 26).call
46
49
 
47
- # Count
50
+ # Count - Counts items on current page. Default page is 1
48
51
  products = ProductsQuery.new(created_at_min: 'Jan 1, 2019').count
49
52
  products = ProductsQuery.new(name: 'Bag').count
53
+
54
+ # Total Count - Counts all items matching defined conditions
55
+ products = ProductsQuery.new(created_at_min: 'Jan 1, 2019').total_count
56
+ products = ProductsQuery.new(name: 'Bag').total_count
50
57
  ```
51
58
 
59
+
52
60
  #### Object Methods
53
61
  - **count** - Returns the filtered count including pagination filter or the size of return object.
54
62
  - **total_count** - Returns the overall count of the filtered total records.
@@ -62,19 +70,84 @@ query = ProductsQuery.new(page: 5, limit: 5)
62
70
  query.count # 1
63
71
  query.total_count # 21
64
72
  ```
73
+ ### Pagination
74
+ Override these methods to customize pagination limits
75
+
76
+ ``` ruby
77
+ ...
78
+
79
+ def upper_limit
80
+ 20 # default is 100
81
+ end
82
+
83
+ def lower_limit
84
+ 5 # default is 10
85
+ end
86
+
87
+ def default_limit
88
+ 10 # default is 50
89
+ end
90
+
91
+ ...
92
+ ```
93
+
94
+ ### Custom Filters
95
+ Create a custom filter class using `Queryko::Filters::Base`
96
+
97
+ ``` ruby
98
+ class CustomFilters::CoolSearch < Queryko::Filters::Base
99
+
100
+ # Optional.
101
+ # Some `options` keys are reserved for basic functionality
102
+ # Use `options` to get data from feature definition
103
+ def intialize(options = {}, feature)
104
+ super options, feature
105
+ end
106
+
107
+ # Required. This method is called by query object. Always return the result of
108
+ # the collection
109
+ def perform(collection, token)
110
+ collection.where("#{table_name}.#{column_name} < ?", "Cool-#{token}")
111
+ end
112
+ end
113
+ ```
114
+
115
+ Then add the filter class to your Queryko::Base object
116
+ ``` ruby
117
+ class QueryObject < Queryko::Base
118
+ filter_class :cool_search, CustomFilters::CoolSearch
119
+ # or
120
+ filter_class :cool_search, "CustomFilters::CoolSearch"
121
+
122
+
123
+ feature :name, :cool_search
124
+ # the :name will be scoped using params[:name_cool_search]
125
+ end
126
+ ```
65
127
 
66
128
  ### Other available options
67
129
  | Option | description |
68
130
  |:---------|:-----------------------------|
69
131
  | since_id | retrieves records after `id` |
70
132
  | page | page to retrieve |
71
- | limit | number of records per page |
133
+
134
+
135
+ ### File structure
136
+ You are free to structure your query objects and custom filters. Or group them
137
+ in one folder
138
+ ```
139
+ app/
140
+ └─ queries/
141
+ ├─ filters/
142
+ │ └─ cool_search.rb
143
+ ├─ products_query.rb
144
+ └─ query_base.rb
145
+ ```
72
146
 
73
147
  ## Contributing
74
148
 
75
149
  Bug reports and pull requests are welcome on GitHub at https://github.com/neume/queryko. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
76
150
 
77
-
78
151
  ## License
79
152
 
80
153
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,78 @@
1
+ require "active_support/core_ext/class/attribute"
2
+ require "queryko/naming"
3
+ require "queryko/able"
4
+ require "queryko/filterer"
5
+ require "queryko/filter_classes"
6
+ require "byebug"
7
+
8
+ module Queryko
9
+
10
+ class Base
11
+ attr_reader :countable_resource
12
+ include Queryko::FilterClasses
13
+ include Queryko::Naming
14
+ include Queryko::Able
15
+ include Queryko::Filterer
16
+
17
+ attr_reader :params
18
+
19
+ def initialize(params = {}, rel=nil)
20
+ @relation = @original_relation = rel || self.class.model_class.all
21
+ @params = self.defaults.merge(params)
22
+ end
23
+
24
+ def self.call(params = {}, rel)
25
+ new(params, rel).call
26
+ end
27
+
28
+ def call
29
+ perform
30
+ return relation
31
+ end
32
+
33
+ def perform
34
+ return if @performed
35
+
36
+ @performed = true
37
+ filter
38
+ filter_by_filters
39
+ @countable_resource = relation
40
+ end
41
+
42
+
43
+ def self.total_count(params = {}, rel)
44
+ new(params, rel).total_count
45
+ end
46
+
47
+ def total_count
48
+ perform
49
+ countable_resource.count
50
+ end
51
+
52
+ def self.count(params = {}, rel)
53
+ new(params, rel).count
54
+ end
55
+
56
+ def count
57
+ call.to_a.count
58
+ end
59
+
60
+ private
61
+
62
+ attr_accessor :relation
63
+
64
+ def config
65
+ @config ||= {
66
+ }
67
+ end
68
+
69
+ def filter
70
+ # overridable method
71
+ end
72
+
73
+ class_attribute :defaults, default: {}
74
+ def self.default(sym, value)
75
+ self.defaults[sym] = value
76
+ end
77
+ end
78
+ end
@@ -4,6 +4,9 @@ require "queryko/filters/before"
4
4
  require "queryko/filters/min"
5
5
  require "queryko/filters/max"
6
6
  require "queryko/filters/search"
7
+ require "queryko/filters/order"
8
+ require "queryko/filters/batch"
9
+ require "queryko/filters/paginate"
7
10
 
8
11
  module Queryko
9
12
  module FilterClasses
@@ -22,7 +25,10 @@ module Queryko
22
25
  before: Queryko::Filters::Before,
23
26
  min: Queryko::Filters::Min,
24
27
  max: Queryko::Filters::Max,
25
- search: Queryko::Filters::Search
28
+ search: Queryko::Filters::Search,
29
+ order: Queryko::Filters::Order,
30
+ batch: Queryko::Filters::Batch,
31
+ paginate: Queryko::Filters::Paginate
26
32
  }
27
33
  end
28
34
 
@@ -2,10 +2,17 @@ module Queryko
2
2
  module Filterer
3
3
  def filter_by_filters
4
4
  fields.each do |field, filter|
5
- # puts field
6
- # puts filter, filter.first.class.name
5
+ if field == 'limit' || field == 'page'
6
+ paginate(filter, )
7
+ end
7
8
  self.relation = filter.first.call(relation, params[field], self) if params[field]
8
9
  end
9
10
  end
11
+
12
+ def paginate(filter)
13
+ unless @paginated
14
+ end
15
+ @paginated ||= true
16
+ end
10
17
  end
11
18
  end
@@ -1,11 +1,7 @@
1
1
  require "queryko/filters/base"
2
2
 
3
3
  class Queryko::Filters::After < Queryko::Filters::Base
4
- def intialize(options = {}, feature)
5
- super options, feature
6
- end
7
-
8
- def perform(collection, token, query_object)
4
+ def perform(collection, token, query_object = nil)
9
5
  collection.where("#{table_name}.#{column_name} > ?", token)
10
6
  end
11
7
  end
@@ -5,7 +5,7 @@ module Queryko
5
5
 
6
6
  def initialize(options = {}, feature)
7
7
  @feature = feature
8
- @table_name = options.fetch(:table_name) { @feature.query_object.defined_table_name }
8
+ @table_name = options[:table_name]
9
9
  @column_name = options.fetch(:column_name) { @feature.name }
10
10
  @as = options[:as]
11
11
  end
@@ -18,11 +18,25 @@ module Queryko
18
18
  end
19
19
 
20
20
  def field
21
- @field ||= as || build_field_from_column
21
+ @field ||= as || build_param_key
22
22
  end
23
23
 
24
- def build_field_from_column
25
- "#{column_name}_#{self.class.name.split('::').last.underscore}"
24
+ def param_key_format
25
+ nil
26
+ end
27
+
28
+ private
29
+
30
+ def build_param_key
31
+ param_key_format || default_param_key_format
32
+ end
33
+
34
+ def default_param_key_format
35
+ "#{column_name}_#{parameterized_name}"
36
+ end
37
+
38
+ def parameterized_name
39
+ self.class.name.split('::').last.underscore
26
40
  end
27
41
  end
28
42
  end
@@ -0,0 +1,11 @@
1
+ require "queryko/filters/base"
2
+
3
+ class Queryko::Filters::Batch < Queryko::Filters::Base
4
+ def perform(collection, token, query_object = nil)
5
+ collection.where("#{table_name}.#{column_name} IN (?)", token.split(','))
6
+ end
7
+
8
+ def param_key_format
9
+ "by_#{column_name.pluralize}"
10
+ end
11
+ end
@@ -1,11 +1,7 @@
1
1
  require "queryko/filters/base"
2
2
 
3
3
  class Queryko::Filters::Before < Queryko::Filters::Base
4
- def intialize(options = {}, feature)
5
- super options, feature
6
- end
7
-
8
- def perform(collection, token, query_object)
4
+ def perform(collection, token, query_object = nil)
9
5
  collection.where("#{table_name}.#{column_name} < ?", token)
10
6
  end
11
7
  end
@@ -1,11 +1,7 @@
1
1
  require "queryko/filters/base"
2
2
 
3
3
  class Queryko::Filters::Max < Queryko::Filters::Base
4
- def intialize(options = {}, feature)
5
- super options, feature
6
- end
7
-
8
- def perform(collection, token, query_object)
4
+ def perform(collection, token, query_object = nil)
9
5
  collection.where("#{table_name}.#{column_name} <= ?", token)
10
6
  end
11
7
  end
@@ -1,15 +1,10 @@
1
1
  require "queryko/filters/base"
2
2
 
3
3
  class Queryko::Filters::Min < Queryko::Filters::Base
4
- def intialize(options = {}, feature)
5
- super options, feature
6
- end
7
-
8
- def perform(collection, token, query_object)
4
+ def perform(collection, token, query_object = nil)
9
5
  collection.where("#{table_name}.#{column_name} >= ?", token)
10
6
  end
11
7
 
12
-
13
8
  def build_field_from_column
14
9
  "#{column_name}_min"
15
10
  end
@@ -0,0 +1,17 @@
1
+ require "queryko/filters/base"
2
+
3
+ class Queryko::Filters::Order < Queryko::Filters::Base
4
+
5
+ def perform(collection, token, query_object = nil)
6
+ collection.order("#{table_name}.#{column_name} #{filter_input(token)}", )
7
+ end
8
+
9
+ def filter_input(token)
10
+ return 'DESC' if token.to_s.downcase == 'desc'
11
+ return 'ASC'
12
+ end
13
+
14
+ def param_key_format
15
+ "order_by_#{column_name}"
16
+ end
17
+ end
@@ -0,0 +1,49 @@
1
+ require "queryko/filters/base"
2
+
3
+ class Queryko::Filters::Paginate < Queryko::Filters::Base
4
+ attr_reader :upper_limit, :lower_limit, :default_limit, :params
5
+
6
+ def initialize(options = {}, feature)
7
+ @upper_limit = options.fetch(:upper) { 100 }
8
+ @lower_limit = options.fetch(:lower) { 10 }
9
+
10
+ super(options, feature)
11
+ end
12
+
13
+ def perform(collection, paginate, query_object)
14
+ if paginate
15
+ @params = query_object.params
16
+
17
+ if defined?(WillPaginate)
18
+ collection.paginate(page: page, per_page: limit)
19
+ elsif defined?(Kaminari)
20
+ collection.page(page).per(limit)
21
+ else
22
+ raise 'Only kaminari and wil_paginate are supported'
23
+ end
24
+ end
25
+ end
26
+
27
+ def page
28
+ params[:page] || 1
29
+ end
30
+
31
+ def limit
32
+ get_limit
33
+ end
34
+
35
+ def get_limit
36
+ lim = params[:limit].to_i
37
+ if lower_limit > lim
38
+ lower_limit
39
+ elsif lim > upper_limit
40
+ upper_limit
41
+ else
42
+ lim
43
+ end
44
+ end
45
+
46
+ def param_key_format
47
+ "paginate"
48
+ end
49
+ end
@@ -5,10 +5,10 @@ class Queryko::Filters::Search < Queryko::Filters::Base
5
5
  def initialize(options = {}, feature)
6
6
  @cond = options.fetch(:cond) { :like }
7
7
  @token_format = options[:token_format] || '%token%'
8
- super options, feature
8
+ super(options, feature)
9
9
  end
10
10
 
11
- def perform(collection, token, query_object)
11
+ def perform(collection, token, query_object = nil)
12
12
  query_cond, query_token = format_query_params(token)
13
13
  table_property = "#{table_name}.#{column_name}"
14
14
 
@@ -3,8 +3,9 @@ module Queryko
3
3
  def self.included(base)
4
4
  base.extend(ClassMethods)
5
5
  base.class_eval do
6
- class_attribute :defined_table_name, default: nil, instance_writer: false
7
- class_attribute :defined_model_class, default: nil, instance_writer: false
6
+ class_attribute :defined_table_name, default: :table, instance_writer: false
7
+ class_attribute :defined_model_class, default: :model, instance_writer: false
8
+ # class_attribute :abstract_class, default: false, instance_writer: false
8
9
 
9
10
  def table_name
10
11
  self.class.table_name
@@ -20,7 +21,7 @@ module Queryko
20
21
  def table_name(name = nil)
21
22
  if name
22
23
  self.defined_table_name = name.to_s
23
- elsif self.defined_table_name.nil?
24
+ elsif self.defined_table_name == :table
24
25
  self.defined_table_name = inferred_from_class_name(self)
25
26
  end
26
27
 
@@ -30,13 +31,19 @@ module Queryko
30
31
  def model_class(name = nil)
31
32
  if name
32
33
  self.defined_model_class = name.to_s.constantize
33
- elsif self.defined_model_class.nil?
34
+ elsif self.defined_model_class == :model
34
35
  self.defined_model_class = inferred_model(self)
35
36
  end
36
37
 
38
+ # require 'byebug'
39
+ # byebug
37
40
  return self.defined_model_class
38
41
  end
39
42
 
43
+ def abstract_class
44
+ @abstract_class = true
45
+ end
46
+
40
47
  def inferred_from_class_name(klass)
41
48
  # class names should be in plural form by default. No need to tableize
42
49
  klass.name.chomp('Query').split('::').last.underscore
@@ -1,3 +1,3 @@
1
1
  module Queryko
2
- VERSION = "1.2.4"
2
+ VERSION = "2.0.0"
3
3
  end
data/lib/queryko.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require "queryko/version"
2
- require "queryko/query_object"
2
+ require "queryko/base"
3
3
  require "queryko/feature"
4
4
  require "queryko/able"
5
5
  require "queryko/filterer"
data/queryko.gemspec CHANGED
@@ -41,4 +41,5 @@ Gem::Specification.new do |spec|
41
41
  spec.add_development_dependency 'sqlite3'
42
42
  spec.add_development_dependency 'kaminari'
43
43
  spec.add_development_dependency 'will_paginate', '~> 3.1.0'
44
+ spec.add_development_dependency 'byebug'
44
45
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: queryko
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.4
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joseph Nelson Valeros
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-06-11 00:00:00.000000000 Z
11
+ date: 2019-06-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: 3.1.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: byebug
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
125
139
  description: " This gem provides additional functionality on your query objects. It
126
140
  will filter and paginate your query by supplying an option "
127
141
  email:
@@ -144,23 +158,22 @@ files:
144
158
  - bin/setup
145
159
  - lib/queryko.rb
146
160
  - lib/queryko/able.rb
147
- - lib/queryko/after_attributes.rb
161
+ - lib/queryko/base.rb
148
162
  - lib/queryko/feature.rb
149
163
  - lib/queryko/filter_classes.rb
150
164
  - lib/queryko/filterer.rb
151
165
  - lib/queryko/filters/after.rb
152
166
  - lib/queryko/filters/base.rb
167
+ - lib/queryko/filters/batch.rb
153
168
  - lib/queryko/filters/before.rb
154
169
  - lib/queryko/filters/max.rb
155
170
  - lib/queryko/filters/min.rb
171
+ - lib/queryko/filters/order.rb
172
+ - lib/queryko/filters/paginate.rb
156
173
  - lib/queryko/filters/search.rb
157
174
  - lib/queryko/naming.rb
158
- - lib/queryko/query_object.rb
159
- - lib/queryko/range_attributes.rb
160
- - lib/queryko/searchables.rb
161
175
  - lib/queryko/version.rb
162
176
  - queryko.gemspec
163
- - test.html
164
177
  homepage: https://github.com/neume/queryko
165
178
  licenses:
166
179
  - MIT
@@ -1,19 +0,0 @@
1
- module Queryko
2
- module AfterAttributes
3
- def self.included(base)
4
- base.extend(ClassMethods)
5
- end
6
-
7
- module ClassMethods
8
- def add_after_attributes(*args)
9
- suggestion = []
10
- args.each do |arg|
11
- feature arg.to_sym, :after, as: "after_#{arg}"
12
- suggestion << "feature :#{arg}, :after, as: 'after_#{arg}'"
13
-
14
- end
15
- warn "[DEPRECATION] `add_after_attributes` is deprecated. Please use `feature` instead.\nExample:\n#{suggestion.join("\n")}"
16
- end
17
- end
18
- end
19
- end