search_object 1.1.1 → 1.1.2

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
  SHA1:
3
- metadata.gz: f8e073aa014abee0b28d16becee73863464fd881
4
- data.tar.gz: 3bc4009abae195732fc8d20e77e4c42b8f080c13
3
+ metadata.gz: dfd3ff677d11a1e11bed9b477960df1e286a162d
4
+ data.tar.gz: 60cabe41c79f8596ce290c52cfe88317fb28fd00
5
5
  SHA512:
6
- metadata.gz: b39a094a23b0721756303b3988e12acded95e775bd649b15ea9a7a0f0941d79cf0362d78a46ba56154273ed93c7bb8c1a18788255313a5ed290abf9505346a52
7
- data.tar.gz: 7ae9c659722f908b487d44fd099a5e4aca80465624cf5849412384cef82c3a2632d930480fac40814c5b3c2c911ee129bf88b03302e3908acf9184b2d371cd2b
6
+ metadata.gz: 331c98690d13135b9a3fb0427c9a6df1139785af9df0c53755fddd1c30db4b93c48a38f094156829f4d6a419eea9ba1b381f9fcd105dabcb06f04a6a936acaf4
7
+ data.tar.gz: c9d14a709fd31ad3cdafdda6ce8028edd80da3549ae6e0c0e96e4f9afa64384cf3805a258f46776a684ed19c605f7d69e472e96864d4ac30cb874ebad03f7c92
data/.rubocop.yml CHANGED
@@ -26,6 +26,14 @@ Style/EachWithObject:
26
26
  Style/CollectionMethods:
27
27
  Enabled: false
28
28
 
29
- # Disables "Example has too many lines"
29
+ # Disables "Block has too many lines."
30
+ Metrics/BlockLength:
31
+ Enabled: false
32
+
33
+ # Disables "Example has too many lines."
30
34
  RSpec/ExampleLength:
31
35
  Enabled: false
36
+
37
+ # Disables "Too many expectations."
38
+ RSpec/MultipleExpectations:
39
+ Enabled: false
data/.travis.yml CHANGED
@@ -1,8 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.0
4
- - 2.1
5
3
  - 2.2
4
+ - 2.3
6
5
  script:
7
6
  - bundle exec rubocop
8
7
  - bundle exec rspec spec
data/CHANGELOG.md CHANGED
@@ -1,12 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## Version 1.1.2
4
+
5
+ * __[fix]__ Fix a warning due to Rails 5 `ActionController::Parameters` not being a Hash (@rstankov)
6
+ * __[fix]__ Ensure `sort_by` prefixes with table_name. (@andreasklinger)
7
+
3
8
  ## Version 1.1.1
4
9
 
5
- * Fix a bug in inheriting search objects
10
+ * __[fix]__ Fix a bug in inheriting search objects (@avlazarov)
6
11
 
7
12
  ## Version 1.1
8
13
 
9
- * Search objects now can be inherited
14
+ * __[feature]__ Search objects now can be inherited (@rstankov)
10
15
 
11
16
  ```ruby
12
17
  class BaseSearch
@@ -20,7 +25,7 @@
20
25
  end
21
26
  ```
22
27
 
23
- * Using instance method for straight dispatch
28
+ * __[feature]__ Use instance method for straight dispatch (@gsamokovarov)
24
29
 
25
30
  ```ruby
26
31
  class ProductSearch
@@ -28,31 +33,25 @@
28
33
 
29
34
  scope { Product.all }
30
35
 
31
- option :name
32
- option :category_name
36
+ option :date, with: :parse_dates
33
37
 
34
- attr_reader :page
35
-
36
- def initialize(filters = {}, page = 0)
37
- super filters
38
- @page = page.to_i.abc
39
- end
38
+ private
40
39
 
41
- def fetch_results
42
- super.paginate page: @page
40
+ def parse_dates(scope, value)
41
+ # some "magic" method to parse dates
43
42
  end
44
43
  end
45
44
  ```
46
45
 
47
46
  ## Version 1.0
48
47
 
49
- * Added min_per_page and max_per_page to paging plugin
48
+ * __[feature]__ Added min_per_page and max_per_page to paging plugin (@rstankov)
50
49
 
51
- * Default paging behaves more like 'kaminari' and 'will_paginate' by treating 1 page as 0 index (__backward incompatible__)
50
+ * __[change]__ Default paging behaves more like 'kaminari' and 'will_paginate' by treating 1 page as 0 index (__backward incompatible__) (@rstankov)
52
51
 
53
- * Raise `SearchObject::MissingScopeError` when no scope is provided
52
+ * __[feature]__ Raise `SearchObject::MissingScopeError` when no scope is provided (@rstankov)
54
53
 
55
- * Replace position arguments with Hash of options (__backward incompatible__)
54
+ * __[change]__ Replace position arguments with Hash of options (__backward incompatible__) (@rstankov)
56
55
 
57
56
  ```diff
58
57
  - Search.new params[:f], params[:page]
@@ -61,10 +60,10 @@
61
60
 
62
61
  ## Version 0.2
63
62
 
64
- * Added `.results` shortcut for `new(*arg).results`
63
+ * __[feature]__ Added `.results` shortcut for `new(*arg).results` (@rstankov)
65
64
 
66
- * Fix wrong limit and offset in default paging
65
+ * __[fix]__ Fix wrong limit and offset in default paging (@rstankov)
67
66
 
68
67
  ## Version 0.1
69
68
 
70
- * Initial release
69
+ * Initial release (@rstankov)
data/README.md CHANGED
@@ -293,7 +293,7 @@ class ProductSearch
293
293
 
294
294
  def initialize(filters = {}, page = 0)
295
295
  super filters
296
- @page = page.to_i.abc
296
+ @page = page.to_i.abs
297
297
  end
298
298
 
299
299
  def fetch_results
data/example/Gemfile CHANGED
@@ -1,11 +1,12 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'rails', '4.2.0'
4
- gem 'sqlite3'
3
+ gem 'rails', '5.0.1'
4
+
5
+ gem 'bootstrap-sass'
6
+ gem 'jquery-rails'
7
+ gem 'rspec-rails'
5
8
  gem 'sass-rails', '~> 5.0.0'
6
9
  gem 'slim'
7
- gem 'jquery-rails'
8
- gem 'bootstrap-sass'
10
+ gem 'sqlite3'
9
11
  gem 'will_paginate'
10
12
  gem 'will_paginate-bootstrap'
11
- gem 'rspec-rails'
@@ -13,8 +13,8 @@ Example::Application.configure do
13
13
  config.eager_load = false
14
14
 
15
15
  # Configure static asset server for tests with Cache-Control for performance.
16
- config.serve_static_files = true
17
- config.static_cache_control = "public, max-age=3600"
16
+ config.public_file_server.enabled = true
17
+ config.public_file_server.headers = { 'Cache-Control' => 'public, max-age=3600' }
18
18
 
19
19
  # Show full error reports and disable caching.
20
20
  config.consider_all_requests_local = true
@@ -74,10 +74,10 @@ describe PostSearch do
74
74
  end
75
75
 
76
76
  it 'can sort by views count' do
77
- post_3 = create views_count: 3
78
- post_2 = create views_count: 2
79
- post_1 = create views_count: 1
77
+ post3 = create views_count: 3
78
+ post2 = create views_count: 2
79
+ post1 = create views_count: 1
80
80
 
81
- expect_search(sort: 'views_count').to eq [post_3, post_2, post_1]
81
+ expect_search(sort: 'views_count').to eq [post3, post2, post1]
82
82
  end
83
83
  end
@@ -1,11 +1,15 @@
1
1
  module SearchObject
2
+ # :api: private
2
3
  module Helper
3
4
  class << self
4
5
  def stringify_keys(hash)
6
+ # Note(rstankov): From Rails 5+ ActionController::Parameters aren't Hash
7
+ # In a lot of cases `stringify_keys` is used on action params
8
+ hash = hash.to_unsafe_h if hash.respond_to? :to_unsafe_h
5
9
  Hash[(hash || {}).map { |k, v| [k.to_s, v] }]
6
10
  end
7
11
 
8
- def select_keys(hash, keys)
12
+ def slice_keys(hash, keys)
9
13
  keys.inject({}) do |memo, key|
10
14
  memo[key] = hash[key] if hash.key? key
11
15
  memo
@@ -5,7 +5,7 @@ module SearchObject
5
5
  base.extend ClassMethods
6
6
  base.instance_eval do
7
7
  option :sort do |scope, _|
8
- scope.order "#{sort_attribute} #{sort_direction}"
8
+ scope.order sort_attribute => sort_direction
9
9
  end
10
10
  end
11
11
  end
@@ -10,7 +10,7 @@ module SearchObject
10
10
  private
11
11
 
12
12
  def apply_paging(scope)
13
- scope.paginate per_page: per_page, page: page == 0 ? nil : page
13
+ scope.paginate per_page: per_page, page: page.zero? ? nil : page
14
14
  end
15
15
  end
16
16
  end
@@ -6,7 +6,7 @@ module SearchObject
6
6
  def build_for(config, options)
7
7
  scope = options.fetch(:scope) { config[:scope] && config[:scope].call }
8
8
  filters = Helper.stringify_keys(options.fetch(:filters, {}))
9
- params = config[:defaults].merge Helper.select_keys(filters, config[:actions].keys)
9
+ params = config[:defaults].merge Helper.slice_keys(filters, config[:actions].keys)
10
10
 
11
11
  raise MissingScopeError unless scope
12
12
 
@@ -1,3 +1,3 @@
1
1
  module SearchObject
2
- VERSION = '1.1.1'.freeze
2
+ VERSION = '1.1.2'.freeze
3
3
  end
@@ -18,15 +18,16 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.3"
21
+ spec.add_development_dependency "bundler", "~> 1.13"
22
22
  spec.add_development_dependency "rake"
23
- spec.add_development_dependency 'rspec', '~> 2.14'
24
- spec.add_development_dependency 'rspec-mocks', '>= 2.12.3'
25
- spec.add_development_dependency 'activerecord', '>= 3.0.0'
23
+ spec.add_development_dependency 'rspec', '~> 3.5'
24
+ spec.add_development_dependency 'rspec-mocks', '~> 3.5'
25
+ spec.add_development_dependency 'activerecord', '~> 5.0'
26
+ spec.add_development_dependency 'actionpack', '~> 5.0'
26
27
  spec.add_development_dependency 'sqlite3'
27
28
  spec.add_development_dependency 'coveralls'
28
29
  spec.add_development_dependency 'will_paginate'
29
30
  spec.add_development_dependency 'kaminari'
30
- spec.add_development_dependency 'rubocop', '0.40.0'
31
- spec.add_development_dependency 'rubocop-rspec', '1.5.0'
31
+ spec.add_development_dependency 'rubocop', '0.46.0'
32
+ spec.add_development_dependency 'rubocop-rspec', '1.8.0'
32
33
  end
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'action_controller'
2
3
 
3
4
  module SearchObject
4
5
  describe Helper do
@@ -7,16 +8,22 @@ module SearchObject
7
8
  hash = Helper.stringify_keys a: 1, b: nil, c: false
8
9
  expect(hash).to eq 'a' => 1, 'b' => nil, 'c' => false
9
10
  end
11
+
12
+ it 'converts ActionController::Parameters to hash' do
13
+ params = ::ActionController::Parameters.new a: 1, b: nil, c: false
14
+ hash = Helper.stringify_keys params
15
+ expect(hash).to eq 'a' => 1, 'b' => nil, 'c' => false
16
+ end
10
17
  end
11
18
 
12
- describe '.select_keys' do
19
+ describe '.slice_keys' do
13
20
  it 'selects only given keys' do
14
- hash = Helper.select_keys({ a: 1, b: 2, c: 3 }, [:a, :b])
21
+ hash = Helper.slice_keys({ a: 1, b: 2, c: 3 }, [:a, :b])
15
22
  expect(hash).to eq a: 1, b: 2
16
23
  end
17
24
 
18
25
  it 'ignores not existing keys' do
19
- hash = Helper.select_keys({}, [:a, :b])
26
+ hash = Helper.slice_keys({}, [:a, :b])
20
27
  expect(hash).to eq({})
21
28
  end
22
29
  end
@@ -25,9 +25,7 @@ module SearchObject
25
25
  describe ExtendedModel do
26
26
  include ActiveModel::Lint::Tests
27
27
 
28
- before do
29
- @model = subject
30
- end
28
+ let(:model) { subject }
31
29
 
32
30
  def assert(condition, message = nil)
33
31
  expect(condition).to be_truthy, message
@@ -9,10 +9,11 @@ module SearchObject
9
9
 
10
10
  scope { Product.all }
11
11
 
12
- sort_by :name, :price
12
+ sort_by :name, :price, :created_at
13
13
 
14
14
  option :name
15
15
  option :price
16
+ option(:category) { |scope, _| scope.joins(:category) }
16
17
  end
17
18
  end
18
19
 
@@ -48,6 +49,18 @@ module SearchObject
48
49
  search = search_with_sort 'invalid attribute'
49
50
  expect { search.results.to_a }.not_to raise_error
50
51
  end
52
+
53
+ it 'can handle renames of sorting in joins' do
54
+ older_category = Category.create! name: 'older'
55
+ newer_category = Category.create! name: 'newer'
56
+
57
+ product_of_newer_category = Product.create! name: 'older product', category: newer_category
58
+ product_of_older_category = Product.create! name: 'newer product', category: older_category
59
+
60
+ search = search_with_sort 'created_at desc', category: ''
61
+
62
+ expect(search.results.map(&:name)).to eq [product_of_older_category.name, product_of_newer_category.name]
63
+ end
51
64
  end
52
65
 
53
66
  describe '#sort?' do
@@ -9,12 +9,22 @@ ActiveRecord::Schema.define do
9
9
 
10
10
  create_table :products, force: true do |t|
11
11
  t.string :name
12
- t.string :category_name
12
+ t.integer :category_id
13
13
  t.integer :price
14
14
 
15
15
  t.timestamps null: true
16
16
  end
17
+
18
+ create_table :categories, force: true do |t|
19
+ t.string :name
20
+
21
+ t.timestamps null: true
22
+ end
17
23
  end
18
24
 
19
25
  class Product < ActiveRecord::Base
26
+ belongs_to :category
27
+ end
28
+
29
+ class Category < ActiveRecord::Base
20
30
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: search_object
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Radoslav Stankov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-26 00:00:00.000000000 Z
11
+ date: 2016-12-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.3'
19
+ version: '1.13'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.3'
26
+ version: '1.13'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,42 +44,56 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '2.14'
47
+ version: '3.5'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '2.14'
54
+ version: '3.5'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec-mocks
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 2.12.3
61
+ version: '3.5'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 2.12.3
68
+ version: '3.5'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: activerecord
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 3.0.0
75
+ version: '5.0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '5.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: actionpack
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '5.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: 3.0.0
96
+ version: '5.0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: sqlite3
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -142,28 +156,28 @@ dependencies:
142
156
  requirements:
143
157
  - - '='
144
158
  - !ruby/object:Gem::Version
145
- version: 0.40.0
159
+ version: 0.46.0
146
160
  type: :development
147
161
  prerelease: false
148
162
  version_requirements: !ruby/object:Gem::Requirement
149
163
  requirements:
150
164
  - - '='
151
165
  - !ruby/object:Gem::Version
152
- version: 0.40.0
166
+ version: 0.46.0
153
167
  - !ruby/object:Gem::Dependency
154
168
  name: rubocop-rspec
155
169
  requirement: !ruby/object:Gem::Requirement
156
170
  requirements:
157
171
  - - '='
158
172
  - !ruby/object:Gem::Version
159
- version: 1.5.0
173
+ version: 1.8.0
160
174
  type: :development
161
175
  prerelease: false
162
176
  version_requirements: !ruby/object:Gem::Requirement
163
177
  requirements:
164
178
  - - '='
165
179
  - !ruby/object:Gem::Version
166
- version: 1.5.0
180
+ version: 1.8.0
167
181
  description: Search object DSL
168
182
  email:
169
183
  - rstankov@gmail.com