rack-reducer 2.0.0 → 2.0.2

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: 89560b1f9fb58a56452e6e9cbba2a9dd5e0159b938c804628750549da310c543
4
- data.tar.gz: f7e9667193f0e4e6e5b413ceec8506919f784604d5be97746239688f3074ab8b
3
+ metadata.gz: c069005f0502425e332cd99bb9b27d11ab257baa937be74ce96b120e6af1cb70
4
+ data.tar.gz: 7c818a942e2d5b6fe50aa6832c74d11592d76e16d6cd92d31aeb4bc608092a3e
5
5
  SHA512:
6
- metadata.gz: fa641c8d24f2bd6a52f523e447c43d1714c92db33175750b4728512bcdca9f5668a018a4be1b5a504fb3ad0188ace6e5e3911503c6a06d48cbf3d9a64aecf489
7
- data.tar.gz: d60cbdae9d7d225024680262be9be5b8b92a923ad224452dfd7e383410e75d5ee717ac3842b9f0ed95ebb8b3789ef36bc3880794b62577f1162a6d67816df77b
6
+ metadata.gz: 3db32664cc591ecb2efa31d9bb39a4c3efb321e21a8fcabd5355416b7fca771ef9c2c90be57913f9b44bad100c95900e0ca8e2b14fcf3931f32cad8d70cd62e8
7
+ data.tar.gz: fc199821f33b07ae4f3684dd2f56367d89415bd16385ae6bb383df220e4266564ca8d6092443dea1bafbb50378660d173caceef36dd3f3c17d4afe52f7da81fa
data/README.md CHANGED
@@ -161,7 +161,7 @@ class Artist < ApplicationRecord
161
161
  ->(name:) { by_name(name) },
162
162
  ->(genre:) { where(genre: genre) },
163
163
  ->(sort:) { order(sort.to_sym) }
164
- ]
164
+ )
165
165
 
166
166
  scope :by_name, lambda { |name|
167
167
  where('lower(name) like ?', "%#{name.downcase}%")
@@ -51,7 +51,7 @@ module Rack
51
51
  def apply(url_params)
52
52
  if url_params.empty?
53
53
  # Return early with the unfiltered dataset if no default filters exist
54
- return @dataset if @default_filters.empty?
54
+ return fresh_dataset if @default_filters.empty?
55
55
 
56
56
  # Run only the default filters
57
57
  filters, params = @default_filters, EMPTY_PARAMS
@@ -66,7 +66,7 @@ module Rack
66
66
  private
67
67
 
68
68
  def reduce(params, filters)
69
- filters.reduce(@dataset) do |data, filter|
69
+ filters.reduce(fresh_dataset) do |data, filter|
70
70
  next data unless filter.satisfies?(params)
71
71
 
72
72
  data.instance_exec(
@@ -76,6 +76,13 @@ module Rack
76
76
  end
77
77
  end
78
78
 
79
+ # Rails +Model.all+ relations get query-cached by default, which has caused
80
+ # filterless requests to load stale data. This method busts the query cache.
81
+ # See https://github.com/chrisfrank/rack-reducer/issues/11
82
+ def fresh_dataset
83
+ @dataset.clone
84
+ end
85
+
79
86
  EMPTY_PARAMS = {}.freeze
80
87
  private_constant :EMPTY_PARAMS
81
88
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Rack
4
4
  class Reducer
5
- VERSION = '2.0.0'
5
+ VERSION = '2.0.2'
6
6
  end
7
7
  end
@@ -2,9 +2,13 @@ require 'spec_helper'
2
2
  require_relative 'fixtures'
3
3
 
4
4
  Process.respond_to?(:fork) && RSpec.describe('in a Rails app') do
5
+ using SpecRefinements
5
6
  BuildRailsApp = lambda do
6
7
  require 'action_controller/railtie'
8
+ require 'active_record'
7
9
  require 'securerandom'
10
+ require 'sqlite3'
11
+
8
12
  app = Class.new(Rails::Application) do
9
13
  routes.append do
10
14
  get "/", to: "artists#index"
@@ -16,14 +20,33 @@ Process.respond_to?(:fork) && RSpec.describe('in a Rails app') do
16
20
  config.secret_key_base = SecureRandom.hex(64)
17
21
  end
18
22
 
23
+ ActiveRecord::Base.establish_connection("sqlite3::memory:")
24
+ ActiveRecord::Schema.define do
25
+ create_table :artists do |t|
26
+ t.string :name
27
+ t.string :genre
28
+ t.integer :release_count
29
+ end
30
+ end
31
+
32
+ Artist = Class.new(ActiveRecord::Base)
33
+
34
+ Fixtures::DB[:artists].each { |row| Artist.create(row) }
35
+
19
36
  ArtistsController = Class.new(ActionController::API) do
37
+ RailsReducer = Rack::Reducer.new(
38
+ Artist.all,
39
+ ->(name:) { where('lower(name) like ?', "%#{name.downcase}%") },
40
+ ->(genre:) { where(genre: genre) },
41
+ )
42
+
20
43
  def index
21
- @artists = Fixtures::ArtistReducer.apply(params)
44
+ @artists = RailsReducer.apply(params)
22
45
  render json: @artists
23
46
  end
24
47
 
25
48
  def query
26
- @artists = Fixtures::ArtistReducer.apply(request.query_parameters)
49
+ @artists = RailsReducer.apply(request.query_parameters)
27
50
  render json: @artists
28
51
  end
29
52
  end
@@ -47,7 +70,22 @@ Process.respond_to?(:fork) && RSpec.describe('in a Rails app') do
47
70
  Process.wait(pid)
48
71
  end
49
72
 
50
- it 'does not load ActiveSupport into global scope b/c of this spec' do
73
+ it 'tracks updates to the backend between requests' do
74
+ pid = Process.fork do
75
+ get("/") { |res| expect(res.json.count).to eq(6) }
76
+
77
+ Artist.create!(name: "RZA")
78
+
79
+ get("/") { |res| expect(res.json.count).to eq(7) }
80
+
81
+ Artist.find_by(name: "RZA").destroy
82
+
83
+ get("/") { |res| expect(res.json.count).to eq(6) }
84
+ end
85
+ Process.wait(pid)
86
+ end
87
+
88
+ it 'does not pollute the global Ruby scope' do
51
89
  expect { ''.blank? }.to raise_error(NoMethodError)
52
90
  end
53
91
  end
@@ -26,13 +26,6 @@ RSpec.describe 'Rack::Reducer' do
26
26
  end
27
27
  end
28
28
 
29
- it 'resets state between requests' do
30
- get('/artists?name=Blake')
31
- get('/artists') do |res|
32
- expect(res.json.count).to eq(Fixtures::DB[:artists].count)
33
- end
34
- end
35
-
36
29
  it 'filters by a single param, e.g. genre' do
37
30
  get('/artists?genre=electronic') do |response|
38
31
  expect(response.body).to include('Björk')
@@ -64,6 +57,32 @@ RSpec.describe 'Rack::Reducer' do
64
57
  expect(Fixtures::ArtistReducer.apply(nil)).to be_truthy
65
58
  end
66
59
 
60
+ describe 'between requests' do
61
+ original_count = Fixtures::DB[:artists].count
62
+
63
+ it 'resets filter state' do
64
+ get('/artists?name=Blake')
65
+ get('/artists') do |res|
66
+ expect(res.json.count).to eq(Fixtures::DB[:artists].count)
67
+ end
68
+ end
69
+
70
+ it 'tracks updates to the backend' do
71
+ get('/artists')
72
+
73
+ Fixtures::DB[:artists][0][:name] = "Lizzo"
74
+ Fixtures::DB[:artists] << { name: 'New Artist' }
75
+
76
+ get('/artists') do |response|
77
+ expect(response.json.count).to eq(original_count + 1)
78
+ expect(response.json.dig(0, 'name')).to eq('Lizzo')
79
+ end
80
+
81
+ Fixtures::DB[:artists].pop
82
+ Fixtures::DB[:artists][0][:name] = "Blake Mills"
83
+ end
84
+ end
85
+
67
86
  describe 'with default filters' do
68
87
  let(:app) do
69
88
  sort = ->(sort: 'name') { sort_by { |item| item[sort.to_sym] } }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-reducer
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Frank
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-02 00:00:00.000000000 Z
11
+ date: 2019-10-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '5.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activerecord
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5.2'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '5.2'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: benchmark-ips
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -170,14 +184,14 @@ dependencies:
170
184
  requirements:
171
185
  - - "~>"
172
186
  - !ruby/object:Gem::Version
173
- version: '1'
187
+ version: 1.3.6
174
188
  type: :development
175
189
  prerelease: false
176
190
  version_requirements: !ruby/object:Gem::Requirement
177
191
  requirements:
178
192
  - - "~>"
179
193
  - !ruby/object:Gem::Version
180
- version: '1'
194
+ version: 1.3.6
181
195
  - !ruby/object:Gem::Dependency
182
196
  name: yard
183
197
  requirement: !ruby/object:Gem::Requirement