paraphrase 0.7.0 → 0.8.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 +4 -4
- data/.travis.yml +12 -0
- data/Appraisals +4 -0
- data/CHANGELOG.md +53 -0
- data/README.md +132 -81
- data/gemfiles/3.0.gemfile +1 -0
- data/gemfiles/3.0.gemfile.lock +28 -2
- data/gemfiles/3.1.gemfile +1 -0
- data/gemfiles/3.1.gemfile.lock +28 -2
- data/gemfiles/3.2.gemfile +1 -0
- data/gemfiles/3.2.gemfile.lock +28 -2
- data/gemfiles/4.0.gemfile +1 -0
- data/gemfiles/4.0.gemfile.lock +14 -2
- data/lib/paraphrase/active_model.rb +30 -0
- data/lib/paraphrase/query.rb +66 -49
- data/lib/paraphrase/rails.rb +1 -2
- data/lib/paraphrase/scope.rb +56 -0
- data/lib/paraphrase/syntax.rb +15 -60
- data/lib/paraphrase/version.rb +1 -1
- data/lib/paraphrase.rb +1 -0
- data/paraphrase.gemspec +17 -4
- data/spec/paraphrase/query_spec.rb +113 -45
- data/spec/paraphrase/scope_spec.rb +51 -0
- data/spec/paraphrase/syntax_spec.rb +26 -7
- data/spec/spec_helper.rb +60 -1
- metadata +97 -57
- data/CHANGELOG +0 -39
- data/lib/paraphrase/scope_mapping.rb +0 -78
- data/spec/paraphrase/scope_mapping_spec.rb +0 -46
- data/spec/support/database.rb +0 -38
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Paraphrase
|
4
|
+
describe Scope do
|
5
|
+
def build_account_scope(options = {})
|
6
|
+
options.reverse_merge!(
|
7
|
+
keys: [:name],
|
8
|
+
to: :name_like
|
9
|
+
)
|
10
|
+
|
11
|
+
keys = options.delete(:keys)
|
12
|
+
|
13
|
+
Scope.new(keys, options)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#chain" do
|
17
|
+
it "applies scope method to relation with values from params hash" do
|
18
|
+
scope = build_account_scope
|
19
|
+
|
20
|
+
expect(Account).to receive(:name_like).with('Jon Snow')
|
21
|
+
scope.chain({ name: 'Jon Snow' }, Account)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "does nothing if values are missing" do
|
25
|
+
scope = build_account_scope
|
26
|
+
|
27
|
+
expect(Account).not_to receive(:name_like)
|
28
|
+
scope.chain({}, Account)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "passes through blank values if scope has been whitelisted" do
|
32
|
+
scope = build_account_scope(whitelist: true)
|
33
|
+
|
34
|
+
expect(Account).to receive(:name_like).with(nil)
|
35
|
+
scope.chain({}, Account)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'allows whitelisting a subset of keys' do
|
39
|
+
scope = build_account_scope(
|
40
|
+
keys: [:name, :status],
|
41
|
+
to: :with_name_and_status,
|
42
|
+
whitelist: true
|
43
|
+
)
|
44
|
+
|
45
|
+
expect(Account).to receive(:with_name_and_status).with('George', nil)
|
46
|
+
|
47
|
+
scope.chain({ name: 'George' }, Account)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -1,13 +1,32 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
module Paraphrase
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
describe Syntax do
|
5
|
+
class ::AccountQuery < Paraphrase::Query
|
6
|
+
map :name, to: :named
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '.paraphrase' do
|
10
|
+
it "passes through results from an initialized query" do
|
11
|
+
expect_any_instance_of(AccountQuery).to receive(:result).and_call_original
|
12
|
+
|
13
|
+
result = Account.paraphrase
|
14
|
+
expect(result).to eq Account
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'raises if query class is not defined' do
|
18
|
+
expect { User.paraphrase }.to raise_error Paraphrase::NoQueryDefined
|
19
|
+
end
|
20
|
+
|
21
|
+
it "works on instances of `ActiveRecord::Relation`, preserving existing filters" do
|
22
|
+
user = User.create!
|
23
|
+
Account.create!(user: user)
|
24
|
+
Account.create!(name: 'Sophie')
|
25
|
+
account = Account.create!(name: 'Sophie', user: user)
|
26
|
+
|
27
|
+
result = user.accounts.paraphrase(name: 'Sophie')
|
28
|
+
|
29
|
+
expect(result).to eq [account]
|
11
30
|
end
|
12
31
|
end
|
13
32
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,63 @@
|
|
1
1
|
require 'rspec'
|
2
2
|
require 'pry'
|
3
3
|
require 'paraphrase'
|
4
|
-
require '
|
4
|
+
require 'active_record'
|
5
|
+
|
6
|
+
I18n.enforce_available_locales = false
|
7
|
+
|
8
|
+
ActiveRecord::Base.establish_connection(
|
9
|
+
adapter: 'sqlite3',
|
10
|
+
database: ':memory:'
|
11
|
+
)
|
12
|
+
|
13
|
+
ActiveRecord::Migration.verbose = false
|
14
|
+
ActiveRecord::Schema.define do
|
15
|
+
create_table :users, force: true do
|
16
|
+
end
|
17
|
+
|
18
|
+
create_table :posts, force: true do |t|
|
19
|
+
t.string :title
|
20
|
+
t.boolean :published
|
21
|
+
t.datetime :published_at
|
22
|
+
t.references :user
|
23
|
+
end
|
24
|
+
|
25
|
+
create_table :accounts, force: true do |t|
|
26
|
+
t.string :name
|
27
|
+
t.references :user
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
ActiveRecord::Base.extend Paraphrase::Syntax
|
32
|
+
ActiveRecord::Relation.send(:include, Paraphrase::Syntax)
|
33
|
+
|
34
|
+
class User < ActiveRecord::Base
|
35
|
+
has_many :accounts
|
36
|
+
has_many :posts
|
37
|
+
end
|
38
|
+
|
39
|
+
class Post < ActiveRecord::Base
|
40
|
+
belongs_to :user
|
41
|
+
|
42
|
+
scope :titled, ->(title) { where(title: title) }
|
43
|
+
|
44
|
+
def self.published
|
45
|
+
where(published: true)
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.by_users(names)
|
49
|
+
joins(:user).where(users: { name: names })
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.published_between(start_date, end_date)
|
53
|
+
where(published_at: start_date..end_date)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class Account < ActiveRecord::Base
|
58
|
+
belongs_to :user
|
59
|
+
|
60
|
+
def self.named(name)
|
61
|
+
where(name: name)
|
62
|
+
end
|
63
|
+
end
|
metadata
CHANGED
@@ -1,181 +1,222 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: paraphrase
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eduardo Gutierrez
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '3.0'
|
20
|
-
- - <
|
20
|
+
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: '4.1'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '3.0'
|
30
|
-
- - <
|
30
|
+
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '4.1'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: activesupport
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
|
-
- -
|
37
|
+
- - ">="
|
38
38
|
- !ruby/object:Gem::Version
|
39
39
|
version: '3.0'
|
40
|
-
- - <
|
40
|
+
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
version: '4.1'
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
|
-
- -
|
47
|
+
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
49
|
version: '3.0'
|
50
|
-
- - <
|
50
|
+
- - "<"
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '4.1'
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: activemodel
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '3.0'
|
60
|
+
- - "<"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '4.1'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '3.0'
|
70
|
+
- - "<"
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '4.1'
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: actionpack
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '3.0'
|
80
|
+
- - "<"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '4.1'
|
83
|
+
type: :development
|
84
|
+
prerelease: false
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.0'
|
90
|
+
- - "<"
|
51
91
|
- !ruby/object:Gem::Version
|
52
92
|
version: '4.1'
|
53
93
|
- !ruby/object:Gem::Dependency
|
54
94
|
name: bundler
|
55
95
|
requirement: !ruby/object:Gem::Requirement
|
56
96
|
requirements:
|
57
|
-
- - ~>
|
97
|
+
- - "~>"
|
58
98
|
- !ruby/object:Gem::Version
|
59
99
|
version: '1.0'
|
60
100
|
type: :development
|
61
101
|
prerelease: false
|
62
102
|
version_requirements: !ruby/object:Gem::Requirement
|
63
103
|
requirements:
|
64
|
-
- - ~>
|
104
|
+
- - "~>"
|
65
105
|
- !ruby/object:Gem::Version
|
66
106
|
version: '1.0'
|
67
107
|
- !ruby/object:Gem::Dependency
|
68
108
|
name: yard
|
69
109
|
requirement: !ruby/object:Gem::Requirement
|
70
110
|
requirements:
|
71
|
-
- - ~>
|
111
|
+
- - "~>"
|
72
112
|
- !ruby/object:Gem::Version
|
73
113
|
version: '0.7'
|
74
114
|
type: :development
|
75
115
|
prerelease: false
|
76
116
|
version_requirements: !ruby/object:Gem::Requirement
|
77
117
|
requirements:
|
78
|
-
- - ~>
|
118
|
+
- - "~>"
|
79
119
|
- !ruby/object:Gem::Version
|
80
120
|
version: '0.7'
|
81
121
|
- !ruby/object:Gem::Dependency
|
82
122
|
name: rspec
|
83
123
|
requirement: !ruby/object:Gem::Requirement
|
84
124
|
requirements:
|
85
|
-
- - ~>
|
125
|
+
- - "~>"
|
86
126
|
- !ruby/object:Gem::Version
|
87
|
-
version: '2.
|
127
|
+
version: '2.14'
|
88
128
|
type: :development
|
89
129
|
prerelease: false
|
90
130
|
version_requirements: !ruby/object:Gem::Requirement
|
91
131
|
requirements:
|
92
|
-
- - ~>
|
132
|
+
- - "~>"
|
93
133
|
- !ruby/object:Gem::Version
|
94
|
-
version: '2.
|
134
|
+
version: '2.14'
|
95
135
|
- !ruby/object:Gem::Dependency
|
96
|
-
name:
|
136
|
+
name: rake
|
97
137
|
requirement: !ruby/object:Gem::Requirement
|
98
138
|
requirements:
|
99
|
-
- - ~>
|
139
|
+
- - "~>"
|
100
140
|
- !ruby/object:Gem::Version
|
101
|
-
version:
|
141
|
+
version: 0.9.2
|
102
142
|
type: :development
|
103
143
|
prerelease: false
|
104
144
|
version_requirements: !ruby/object:Gem::Requirement
|
105
145
|
requirements:
|
106
|
-
- - ~>
|
146
|
+
- - "~>"
|
107
147
|
- !ruby/object:Gem::Version
|
108
|
-
version:
|
148
|
+
version: 0.9.2
|
109
149
|
- !ruby/object:Gem::Dependency
|
110
|
-
name:
|
150
|
+
name: appraisal
|
111
151
|
requirement: !ruby/object:Gem::Requirement
|
112
152
|
requirements:
|
113
|
-
- - ~>
|
153
|
+
- - "~>"
|
114
154
|
- !ruby/object:Gem::Version
|
115
|
-
version: 0.
|
155
|
+
version: '0.4'
|
116
156
|
type: :development
|
117
157
|
prerelease: false
|
118
158
|
version_requirements: !ruby/object:Gem::Requirement
|
119
159
|
requirements:
|
120
|
-
- - ~>
|
160
|
+
- - "~>"
|
121
161
|
- !ruby/object:Gem::Version
|
122
|
-
version: 0.
|
162
|
+
version: '0.4'
|
123
163
|
- !ruby/object:Gem::Dependency
|
124
|
-
name:
|
164
|
+
name: pry
|
125
165
|
requirement: !ruby/object:Gem::Requirement
|
126
166
|
requirements:
|
127
|
-
- - ~>
|
167
|
+
- - "~>"
|
128
168
|
- !ruby/object:Gem::Version
|
129
|
-
version:
|
169
|
+
version: '0.9'
|
130
170
|
type: :development
|
131
171
|
prerelease: false
|
132
172
|
version_requirements: !ruby/object:Gem::Requirement
|
133
173
|
requirements:
|
134
|
-
- - ~>
|
174
|
+
- - "~>"
|
135
175
|
- !ruby/object:Gem::Version
|
136
|
-
version:
|
176
|
+
version: '0.9'
|
137
177
|
- !ruby/object:Gem::Dependency
|
138
|
-
name:
|
178
|
+
name: redcarpet
|
139
179
|
requirement: !ruby/object:Gem::Requirement
|
140
180
|
requirements:
|
141
|
-
- - ~>
|
181
|
+
- - "~>"
|
142
182
|
- !ruby/object:Gem::Version
|
143
|
-
version:
|
183
|
+
version: 2.1.1
|
144
184
|
type: :development
|
145
185
|
prerelease: false
|
146
186
|
version_requirements: !ruby/object:Gem::Requirement
|
147
187
|
requirements:
|
148
|
-
- - ~>
|
188
|
+
- - "~>"
|
149
189
|
- !ruby/object:Gem::Version
|
150
|
-
version:
|
190
|
+
version: 2.1.1
|
151
191
|
- !ruby/object:Gem::Dependency
|
152
|
-
name:
|
192
|
+
name: sqlite3
|
153
193
|
requirement: !ruby/object:Gem::Requirement
|
154
194
|
requirements:
|
155
|
-
- - ~>
|
195
|
+
- - "~>"
|
156
196
|
- !ruby/object:Gem::Version
|
157
|
-
version:
|
197
|
+
version: 1.3.6
|
158
198
|
type: :development
|
159
199
|
prerelease: false
|
160
200
|
version_requirements: !ruby/object:Gem::Requirement
|
161
201
|
requirements:
|
162
|
-
- - ~>
|
202
|
+
- - "~>"
|
163
203
|
- !ruby/object:Gem::Version
|
164
|
-
version:
|
204
|
+
version: 1.3.6
|
165
205
|
description: "\n Map query params to model scopes, pairing
|
166
206
|
one or\n more keys to a scope. Parameters can be required,
|
167
207
|
or\n whitelisted providing fine tuned control over how\n
|
168
208
|
\ scopes are run.\n "
|
169
|
-
email:
|
209
|
+
email: eduardo@vermonster.com
|
170
210
|
executables: []
|
171
211
|
extensions: []
|
172
212
|
extra_rdoc_files: []
|
173
213
|
files:
|
174
|
-
- .gitignore
|
175
|
-
- .rspec
|
176
|
-
- .
|
214
|
+
- ".gitignore"
|
215
|
+
- ".rspec"
|
216
|
+
- ".travis.yml"
|
217
|
+
- ".yardopts"
|
177
218
|
- Appraisals
|
178
|
-
- CHANGELOG
|
219
|
+
- CHANGELOG.md
|
179
220
|
- Gemfile
|
180
221
|
- LICENSE.txt
|
181
222
|
- README.md
|
@@ -189,18 +230,18 @@ files:
|
|
189
230
|
- gemfiles/4.0.gemfile
|
190
231
|
- gemfiles/4.0.gemfile.lock
|
191
232
|
- lib/paraphrase.rb
|
233
|
+
- lib/paraphrase/active_model.rb
|
192
234
|
- lib/paraphrase/errors.rb
|
193
235
|
- lib/paraphrase/query.rb
|
194
236
|
- lib/paraphrase/rails.rb
|
195
|
-
- lib/paraphrase/
|
237
|
+
- lib/paraphrase/scope.rb
|
196
238
|
- lib/paraphrase/syntax.rb
|
197
239
|
- lib/paraphrase/version.rb
|
198
240
|
- paraphrase.gemspec
|
199
241
|
- spec/paraphrase/query_spec.rb
|
200
|
-
- spec/paraphrase/
|
242
|
+
- spec/paraphrase/scope_spec.rb
|
201
243
|
- spec/paraphrase/syntax_spec.rb
|
202
244
|
- spec/spec_helper.rb
|
203
|
-
- spec/support/database.rb
|
204
245
|
homepage: https://github.com/ecbypi/paraphrase
|
205
246
|
licenses:
|
206
247
|
- MIT
|
@@ -211,24 +252,23 @@ require_paths:
|
|
211
252
|
- lib
|
212
253
|
required_ruby_version: !ruby/object:Gem::Requirement
|
213
254
|
requirements:
|
214
|
-
- -
|
255
|
+
- - ">="
|
215
256
|
- !ruby/object:Gem::Version
|
216
|
-
version:
|
257
|
+
version: 1.9.3
|
217
258
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
218
259
|
requirements:
|
219
|
-
- -
|
260
|
+
- - ">="
|
220
261
|
- !ruby/object:Gem::Version
|
221
262
|
version: '0'
|
222
263
|
requirements: []
|
223
264
|
rubyforge_project:
|
224
|
-
rubygems_version: 2.0
|
265
|
+
rubygems_version: 2.2.0
|
225
266
|
signing_key:
|
226
267
|
specification_version: 4
|
227
268
|
summary: Map query params to model scopes
|
228
269
|
test_files:
|
229
270
|
- spec/paraphrase/query_spec.rb
|
230
|
-
- spec/paraphrase/
|
271
|
+
- spec/paraphrase/scope_spec.rb
|
231
272
|
- spec/paraphrase/syntax_spec.rb
|
232
273
|
- spec/spec_helper.rb
|
233
|
-
- spec/support/database.rb
|
234
274
|
has_rdoc:
|
data/CHANGELOG
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
0.7.0 / 1-25-2014
|
2
|
-
|
3
|
-
* Add Rails 4 support
|
4
|
-
|
5
|
-
0.5.0 / 8-7-2012
|
6
|
-
|
7
|
-
* Cleanup ScopeMapping class
|
8
|
-
* Add ability to query from an existing ActiveRecord::Relation instance
|
9
|
-
(typically an association).
|
10
|
-
* Update syntax for generating mappings.
|
11
|
-
|
12
|
-
0.4.0 / 7-6-2012
|
13
|
-
|
14
|
-
* Setup Query#params to be HashWithIndifferentAccess.
|
15
|
-
* Gut out Paraphrase module methods. These were for use cases I had planned
|
16
|
-
for but have yet to encounter.
|
17
|
-
* Model's query class is now stored on the model itself.
|
18
|
-
|
19
|
-
0.3.2 / 7-5-2012
|
20
|
-
|
21
|
-
* Cache Query#results
|
22
|
-
* Setup Query#method_missing to proxy to Query#results
|
23
|
-
* Setup Query#respond_to? to check Query#results
|
24
|
-
|
25
|
-
0.3.1 / 7-5-2012
|
26
|
-
|
27
|
-
* Fix for rails 3.0
|
28
|
-
|
29
|
-
0.3.0 / 7-5-2012
|
30
|
-
|
31
|
-
* Allow nil values to be passed to scoped using :allow_nil option.
|
32
|
-
* Require/whitelist individual keys of a compound key.
|
33
|
-
* Update Paraphrase::Syntax.register_mapping to update an existing mapping to
|
34
|
-
avoid errors when a model class is reloaded during development.
|
35
|
-
|
36
|
-
0.2.0 / 6-22-2012
|
37
|
-
|
38
|
-
* Initial release
|
39
|
-
|
@@ -1,78 +0,0 @@
|
|
1
|
-
require 'active_support/core_ext/object/blank'
|
2
|
-
|
3
|
-
module Paraphrase
|
4
|
-
class ScopeMapping
|
5
|
-
# @!attribute [r] keys
|
6
|
-
# @return [Array<Symbol>] param keys to extract
|
7
|
-
#
|
8
|
-
# @!attribute [r] method_name
|
9
|
-
# @return [Symbol] scope name
|
10
|
-
#
|
11
|
-
# @!attribute [r] required
|
12
|
-
# @return [Array] keys required for query
|
13
|
-
#
|
14
|
-
# @!attribute [r] whitelist
|
15
|
-
# @return [Array] keys allowed to be nil
|
16
|
-
attr_reader :keys, :method_name, :required, :whitelist
|
17
|
-
|
18
|
-
# @param [Symbol] name name of the scope
|
19
|
-
# @param [Hash] options options to configure {ScopeMapping ScopeMapping} instance
|
20
|
-
# @option options [Symbol, Array<Symbol>] :to param key(s) to extract values from
|
21
|
-
# @option options [true, Symbol, Array<Symbol>] :require lists all or a
|
22
|
-
# subset of param keys as required
|
23
|
-
# @option options [true, Symbol, Array<Symbol>] :whitelist lists all or a
|
24
|
-
# subset of param keys as whitelisted
|
25
|
-
def initialize(name, options)
|
26
|
-
@method_name = name
|
27
|
-
@keys = Array(options.delete(:to))
|
28
|
-
|
29
|
-
@required = register_keys(options[:require])
|
30
|
-
@whitelist = register_keys(options[:whitelist])
|
31
|
-
|
32
|
-
if @whitelist.empty? && !@required.empty?
|
33
|
-
@whitelist = @keys - @required
|
34
|
-
end
|
35
|
-
|
36
|
-
if (whitelist & required).any?
|
37
|
-
raise ArgumentError, "cannot whitelist and require the same keys"
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
# Sends {#method_name} to `chain`, extracting arguments from `params`. If
|
42
|
-
# values are missing for any {#keys}, return the `chain` unmodified.
|
43
|
-
# If {#required? required}, errors are added to the {Query} instance as
|
44
|
-
# well.
|
45
|
-
#
|
46
|
-
# @param [Hash] params hash of query parameters
|
47
|
-
# @param [ActiveRecord::Relation, ActiveRecord::Base] relation scope chain
|
48
|
-
# @return [ActiveRecord::Relation]
|
49
|
-
def chain(params, relation)
|
50
|
-
scope = relation.respond_to?(:klass) ? relation.klass.method(method_name) : relation.method(method_name)
|
51
|
-
|
52
|
-
inputs = keys.map do |key|
|
53
|
-
input = params[key]
|
54
|
-
|
55
|
-
if input.nil?
|
56
|
-
break if required.include?(key)
|
57
|
-
break [] if !whitelist.include?(key)
|
58
|
-
end
|
59
|
-
|
60
|
-
input
|
61
|
-
end
|
62
|
-
|
63
|
-
if inputs.nil?
|
64
|
-
return
|
65
|
-
elsif inputs.empty?
|
66
|
-
return relation
|
67
|
-
end
|
68
|
-
|
69
|
-
scope.arity == 0 ? relation.send(method_name) : relation.send(method_name, *inputs)
|
70
|
-
end
|
71
|
-
|
72
|
-
private
|
73
|
-
|
74
|
-
def register_keys(option)
|
75
|
-
option == true ? Array(keys) : Array(option)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module Paraphrase
|
4
|
-
describe ScopeMapping do
|
5
|
-
|
6
|
-
describe "#chain" do
|
7
|
-
let(:mapping) { ScopeMapping.new(:name_like, :to => :name) }
|
8
|
-
|
9
|
-
it "applies scope method to relation with values from params hash" do
|
10
|
-
Account.should_receive(:name_like).with('Jon Snow')
|
11
|
-
|
12
|
-
mapping.chain({ :name => 'Jon Snow' }, Account)
|
13
|
-
end
|
14
|
-
|
15
|
-
it "does nothing if values are missing" do
|
16
|
-
Account.should_not_receive(:name_like).with('Jon Snow')
|
17
|
-
|
18
|
-
mapping.chain({}, Account)
|
19
|
-
end
|
20
|
-
|
21
|
-
it "passes through nil values if scope has been whitelisted" do
|
22
|
-
mapping = ScopeMapping.new(:name_like, :to => :name, :whitelist => true)
|
23
|
-
|
24
|
-
Account.should_receive(:name_like).with(nil)
|
25
|
-
|
26
|
-
mapping.chain({}, Account)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
describe "compound keys" do
|
31
|
-
let(:compound_mapping) do
|
32
|
-
ScopeMapping.new(:name_like, :to => [:first_name, :last_name], :require => :last_name)
|
33
|
-
end
|
34
|
-
|
35
|
-
it "can require a subset of a compound key" do
|
36
|
-
Account.should_receive(:name_like).with(nil, 'Lannister')
|
37
|
-
|
38
|
-
compound_mapping.chain({ :last_name => 'Lannister' }, Account)
|
39
|
-
end
|
40
|
-
|
41
|
-
it "whitelists the the non-required keys of a compound key" do
|
42
|
-
compound_mapping.whitelist.include?(:first_name).should be_true
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
data/spec/support/database.rb
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
require 'active_record'
|
2
|
-
|
3
|
-
ActiveRecord::Relation.send(:include, Paraphrase::Syntax::Relation)
|
4
|
-
|
5
|
-
ActiveRecord::Base.establish_connection(
|
6
|
-
:adapter => 'sqlite3',
|
7
|
-
:database => ':memory:'
|
8
|
-
)
|
9
|
-
|
10
|
-
ActiveRecord::Migration.verbose = false
|
11
|
-
ActiveRecord::Schema.define do
|
12
|
-
create_table :users, :force => true do
|
13
|
-
end
|
14
|
-
|
15
|
-
create_table :accounts, :force => true do |t|
|
16
|
-
t.references :user
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
class User < ActiveRecord::Base
|
21
|
-
has_many :accounts
|
22
|
-
end
|
23
|
-
|
24
|
-
class Account < ActiveRecord::Base
|
25
|
-
extend Paraphrase::Syntax::Base
|
26
|
-
belongs_to :user
|
27
|
-
|
28
|
-
def self.title_like(*args)
|
29
|
-
ActiveRecord::VERSION::MAJOR > 3 ? all : scoped
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.name_like(*args)
|
33
|
-
ActiveRecord::VERSION::MAJOR > 3 ? all : scoped
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
class AccountQuery < Paraphrase::Query
|
38
|
-
end
|