ii_finder 1.0.0 → 1.2.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/CHANGELOG.md +17 -0
- data/README.md +91 -31
- data/lib/ii_finder/base.rb +7 -52
- data/lib/ii_finder/callbacks.rb +6 -0
- data/lib/ii_finder/chain.rb +38 -0
- data/lib/ii_finder/core.rb +57 -0
- data/lib/ii_finder/instrumentation.rb +13 -0
- data/lib/ii_finder/log_subscriber.rb +18 -0
- data/lib/ii_finder/lookup.rb +5 -5
- data/lib/ii_finder/version.rb +1 -1
- data/lib/ii_finder.rb +1 -0
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2fbbf6a8d97c83f3d098f3b13d93039491698409623d0137e0b170c83dedd58d
|
|
4
|
+
data.tar.gz: 9619799961e2416db17aca506f6ef596acd621b3fc1339aa82679b779d3f79e8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 577f3b00606d238e20a9d24075a92b9b5cdc10f170637e4e6bf6dc58db3bd04bf5de13a75da050af0b7a421d1dfe6bc91b4020188f38051394c39b81133b2fa0
|
|
7
|
+
data.tar.gz: abd2108a7892aa866ffc8d6a86545b61df42ce7b0c10af079e4272f5194e74be5f3c7146ed3ed671a96ea5eb6240edeabe77da8e51ab675b2a05427212bb2adf
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 1.2.0
|
|
4
|
+
|
|
5
|
+
* Add chain feature.
|
|
6
|
+
|
|
7
|
+
## 1.1.2
|
|
8
|
+
|
|
9
|
+
* Try fetch prior to calling instance method.
|
|
10
|
+
|
|
11
|
+
## 1.1.1
|
|
12
|
+
|
|
13
|
+
* Check arel_table existence for model.
|
|
14
|
+
* Make mergeability check more flexible.
|
|
15
|
+
|
|
16
|
+
## 1.1.0
|
|
17
|
+
|
|
18
|
+
* Add log subscriber.
|
|
19
|
+
|
|
3
20
|
## 1.0.0
|
|
4
21
|
|
|
5
22
|
* First release.
|
data/README.md
CHANGED
|
@@ -24,14 +24,14 @@ Then execute:
|
|
|
24
24
|
Prepare model:
|
|
25
25
|
|
|
26
26
|
```ruby
|
|
27
|
-
class
|
|
27
|
+
class Item < ActiveRecord::Base
|
|
28
28
|
end
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
Prepare finder:
|
|
32
32
|
|
|
33
33
|
```ruby
|
|
34
|
-
class
|
|
34
|
+
class ItemsFinder < IIFinder::Base
|
|
35
35
|
parameters :name
|
|
36
36
|
|
|
37
37
|
def name(value)
|
|
@@ -43,15 +43,15 @@ end
|
|
|
43
43
|
Use finder as follows:
|
|
44
44
|
|
|
45
45
|
```ruby
|
|
46
|
-
|
|
47
|
-
#=> SELECT "
|
|
46
|
+
ItemsFinder.call(name: 'NAME').to_sql
|
|
47
|
+
#=> SELECT "items".* FROM "items" WHERE "items"."name" = 'NAME'
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
You can also specify relation as first argument:
|
|
51
51
|
|
|
52
52
|
```ruby
|
|
53
|
-
|
|
54
|
-
#=> SELECT "
|
|
53
|
+
ItemsFinder.call(Item.where(id: [1, 2, 3]), name: 'NAME').to_sql
|
|
54
|
+
#=> SELECT "items".* FROM "items" WHERE "items"."id" IN (1, 2, 3) AND "items"."name" = 'NAME'
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
### Finder
|
|
@@ -61,7 +61,7 @@ Finder method will not be called when the value of parameter is blank.
|
|
|
61
61
|
If you want to receive such value, set `allow_blank` as follows:
|
|
62
62
|
|
|
63
63
|
```ruby
|
|
64
|
-
class
|
|
64
|
+
class ItemsFinder < IIFinder::Base
|
|
65
65
|
parameters :name, allow_blank: true
|
|
66
66
|
|
|
67
67
|
def name(value)
|
|
@@ -69,14 +69,14 @@ class UsersFinder < IIFinder::Base
|
|
|
69
69
|
end
|
|
70
70
|
end
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
#=> SELECT "
|
|
72
|
+
ItemsFinder.call(name: '').to_sql
|
|
73
|
+
#=> SELECT "items".* FROM "items" WHERE "items"."name" = ''
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
Finder has following attributes:
|
|
77
77
|
|
|
78
78
|
```ruby
|
|
79
|
-
class
|
|
79
|
+
class ItemsFinder < IIFinder::Base
|
|
80
80
|
parameters :name
|
|
81
81
|
|
|
82
82
|
def name(value)
|
|
@@ -87,10 +87,10 @@ class UsersFinder < IIFinder::Base
|
|
|
87
87
|
end
|
|
88
88
|
end
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
#=> relation: #<
|
|
90
|
+
ItemsFinder.call(name: 'NAME')
|
|
91
|
+
#=> relation: #<Item::ActiveRecord_Relation:
|
|
92
92
|
# criteria: {:name=>'NAME'}
|
|
93
|
-
# model:
|
|
93
|
+
# model: Item
|
|
94
94
|
# table: #<Arel::Table ...>
|
|
95
95
|
```
|
|
96
96
|
|
|
@@ -102,7 +102,7 @@ IIFinder.configure do |config|
|
|
|
102
102
|
config.merge_relation = false
|
|
103
103
|
end
|
|
104
104
|
|
|
105
|
-
class
|
|
105
|
+
class ItemsFinder < IIFinder::Base
|
|
106
106
|
parameters :name
|
|
107
107
|
|
|
108
108
|
def name(value)
|
|
@@ -110,8 +110,8 @@ class UsersFinder < IIFinder::Base
|
|
|
110
110
|
end
|
|
111
111
|
end
|
|
112
112
|
|
|
113
|
-
|
|
114
|
-
#=> SELECT "
|
|
113
|
+
ItemsFinder.call(name: 'NAME').to_sql
|
|
114
|
+
#=> SELECT "items".* FROM "items" WHERE "items"."name" = 'NAME'
|
|
115
115
|
```
|
|
116
116
|
|
|
117
117
|
#### Callbacks
|
|
@@ -125,7 +125,7 @@ Following callbacks are available.
|
|
|
125
125
|
For example:
|
|
126
126
|
|
|
127
127
|
```ruby
|
|
128
|
-
class
|
|
128
|
+
class ItemsFinder < IIFinder::Base
|
|
129
129
|
after_call :default_order
|
|
130
130
|
|
|
131
131
|
def default_order
|
|
@@ -133,14 +133,59 @@ class UsersFinder < IIFinder::Base
|
|
|
133
133
|
end
|
|
134
134
|
end
|
|
135
135
|
|
|
136
|
-
|
|
137
|
-
#=> SELECT "
|
|
136
|
+
ItemsFinder.call.to_sql
|
|
137
|
+
#=> SELECT "items".* FROM "items" ORDER BY "items"."id" DESC
|
|
138
138
|
```
|
|
139
139
|
|
|
140
140
|
Note that finder does not handle the return value of callback.
|
|
141
141
|
When you want to update `@relation` in the callback,
|
|
142
142
|
reassign `@relation` or use methods like `where!` or `order!`.
|
|
143
143
|
|
|
144
|
+
#### Chain
|
|
145
|
+
|
|
146
|
+
You can chain multiple finders by using `chain`. For example:
|
|
147
|
+
|
|
148
|
+
```ruby
|
|
149
|
+
class NameFinder < IIFinder::Base
|
|
150
|
+
parameters :name
|
|
151
|
+
|
|
152
|
+
def name(value)
|
|
153
|
+
@relation.where(name: value)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
class AgeFinder < IIFinder::Base
|
|
158
|
+
parameters :age
|
|
159
|
+
|
|
160
|
+
def age(value)
|
|
161
|
+
@relation.where(age: value)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
class ItemsFinder < IIFinder::Base
|
|
166
|
+
chain NameFinder, AgeFinder
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
ItemsFinder.call(Item.all, name: 'name', age: 10).to_sql
|
|
170
|
+
#=> SELECT "items".* FROM "items" WHERE "items"."name" = 'name' AND "items"."age" = 10
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
You can also use method or block to find finder class dynamically:
|
|
174
|
+
|
|
175
|
+
```ruby
|
|
176
|
+
class ItemFinder < IIFinder::Base
|
|
177
|
+
chain -> { NameFinder }
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
class ItemFinder < IIFinder::Base
|
|
181
|
+
chain :chain_finder
|
|
182
|
+
|
|
183
|
+
def chain_finder
|
|
184
|
+
NameFinder
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
```
|
|
188
|
+
|
|
144
189
|
### Lookup for model
|
|
145
190
|
|
|
146
191
|
Finder lookups related model by its class name when the first argument of `call` is not relation.
|
|
@@ -148,30 +193,30 @@ So the name of finder class should be composed of the name of model class.
|
|
|
148
193
|
For example:
|
|
149
194
|
|
|
150
195
|
```ruby
|
|
151
|
-
class
|
|
196
|
+
class Item < ActiveRecord::Base
|
|
152
197
|
end
|
|
153
198
|
|
|
154
|
-
class
|
|
199
|
+
class ItemsFinder < IIFinder::Base
|
|
155
200
|
end
|
|
156
201
|
|
|
157
|
-
IIFinder::Base.lookup(
|
|
158
|
-
#=>
|
|
202
|
+
IIFinder::Base.lookup(ItemsFinder)
|
|
203
|
+
#=> Item
|
|
159
204
|
```
|
|
160
205
|
|
|
161
206
|
Note that superclass of finder is also looked up until related model is found.
|
|
162
207
|
|
|
163
208
|
```ruby
|
|
164
|
-
class
|
|
209
|
+
class Item < ActiveRecord::Base
|
|
165
210
|
end
|
|
166
211
|
|
|
167
|
-
class
|
|
212
|
+
class ItemsFinder < IIFinder::Base
|
|
168
213
|
end
|
|
169
214
|
|
|
170
|
-
class
|
|
215
|
+
class InheritedItemsFinder < ItemsFinder
|
|
171
216
|
end
|
|
172
217
|
|
|
173
|
-
IIFinder::Base.lookup(
|
|
174
|
-
#=>
|
|
218
|
+
IIFinder::Base.lookup(InheritedItemsFinder)
|
|
219
|
+
#=> Item
|
|
175
220
|
```
|
|
176
221
|
|
|
177
222
|
### Scope for model
|
|
@@ -179,12 +224,27 @@ IIFinder::Base.lookup(InheritedUsersFinder)
|
|
|
179
224
|
In case you want to call finder from model, include `IIFinder::Scope` into model as follows:
|
|
180
225
|
|
|
181
226
|
```ruby
|
|
182
|
-
class
|
|
227
|
+
class Item < ActiveRecord::Base
|
|
183
228
|
include IIFinder::Scope
|
|
184
229
|
end
|
|
185
230
|
|
|
186
|
-
|
|
187
|
-
#=> SELECT "
|
|
231
|
+
Item.finder_scope(name: 'NAME').to_sql
|
|
232
|
+
#=> SELECT "items".* FROM "items" WHERE "items"."name" = 'NAME'
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Logging
|
|
236
|
+
|
|
237
|
+
Finder supports instrumentation hook supplied by `ActiveSupport::Notifications`.
|
|
238
|
+
You can enable log subscriber as follows:
|
|
239
|
+
|
|
240
|
+
```ruby
|
|
241
|
+
IIFinder::LogSubscriber.attach_to :ii_finder
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
This subscriber will write logs in debug mode as the following example:
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
Called ItemsFinder with {:id=>1} (Duration: 9.9ms, Allocations: 915)
|
|
188
248
|
```
|
|
189
249
|
|
|
190
250
|
## Contributing
|
data/lib/ii_finder/base.rb
CHANGED
|
@@ -1,64 +1,19 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative '
|
|
3
|
+
require_relative 'core'
|
|
4
4
|
require_relative 'parameters'
|
|
5
5
|
require_relative 'callbacks'
|
|
6
|
+
require_relative 'instrumentation'
|
|
7
|
+
require_relative 'lookup'
|
|
8
|
+
require_relative 'chain'
|
|
6
9
|
|
|
7
10
|
module IIFinder
|
|
8
11
|
class Base
|
|
12
|
+
include Core
|
|
9
13
|
include Parameters
|
|
10
14
|
include Callbacks
|
|
15
|
+
include Instrumentation
|
|
11
16
|
include Lookup
|
|
12
|
-
|
|
13
|
-
attr_reader :relation, :criteria, :model, :table
|
|
14
|
-
|
|
15
|
-
def initialize(*args)
|
|
16
|
-
if args.size == 0 || args.size == 1
|
|
17
|
-
@model = self.class.lookup
|
|
18
|
-
raise IIFinder::Error.new("could not find model for #{self.class}") unless @model
|
|
19
|
-
@relation = @model.all
|
|
20
|
-
@criteria = args[0] || {}
|
|
21
|
-
else
|
|
22
|
-
@relation = args[0]
|
|
23
|
-
@criteria = args[1]
|
|
24
|
-
@model = @relation.klass
|
|
25
|
-
end
|
|
26
|
-
@table = @model.arel_table
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def call
|
|
30
|
-
run_callbacks :call do
|
|
31
|
-
self.class._parameters.each do |param|
|
|
32
|
-
value = fetch_criteria(param.name)
|
|
33
|
-
if value.present? || param.allow_blank?
|
|
34
|
-
call_method(param.name, value)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
@relation
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def fetch_criteria(name)
|
|
43
|
-
if @criteria.respond_to?(name)
|
|
44
|
-
@criteria.send(name)
|
|
45
|
-
elsif @criteria.respond_to?(:fetch)
|
|
46
|
-
@criteria.fetch(name, nil)
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def call_method(name, value)
|
|
51
|
-
result = send(name, value)
|
|
52
|
-
|
|
53
|
-
if Config.merge_relation && result.is_a?(ActiveRecord::Relation)
|
|
54
|
-
@relation = @relation.merge(result)
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
class << self
|
|
59
|
-
def call(*args)
|
|
60
|
-
new(*args).call
|
|
61
|
-
end
|
|
62
|
-
end
|
|
17
|
+
include Chain
|
|
63
18
|
end
|
|
64
19
|
end
|
data/lib/ii_finder/callbacks.rb
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module IIFinder
|
|
4
|
+
module Chain
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
class_attribute :_chains
|
|
9
|
+
self._chains = []
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def call
|
|
13
|
+
lookup.each do |finder|
|
|
14
|
+
merge_relation!(finder.call(*@_args))
|
|
15
|
+
end
|
|
16
|
+
super
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def lookup
|
|
20
|
+
self.class._chains.map do |finder|
|
|
21
|
+
if finder.is_a?(Symbol) && respond_to?(finder, true)
|
|
22
|
+
send(finder)
|
|
23
|
+
elsif finder.is_a?(Proc)
|
|
24
|
+
instance_exec(&finder)
|
|
25
|
+
else
|
|
26
|
+
finder
|
|
27
|
+
end
|
|
28
|
+
end.flatten.compact
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class_methods do
|
|
32
|
+
def chain(*finders, &block)
|
|
33
|
+
self._chains = _chains + finders
|
|
34
|
+
self._chains << block if block
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module IIFinder
|
|
4
|
+
module Core
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
attr_reader :relation, :criteria, :model, :table
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def initialize(*args)
|
|
12
|
+
@_args = args;
|
|
13
|
+
if args.size == 0 || args.size == 1
|
|
14
|
+
@model = self.class.lookup
|
|
15
|
+
raise IIFinder::Error.new("could not find model for #{self.class}") unless @model
|
|
16
|
+
@relation = @model.all
|
|
17
|
+
@criteria = args[0] || {}
|
|
18
|
+
else
|
|
19
|
+
@relation = args[0]
|
|
20
|
+
@criteria = args[1]
|
|
21
|
+
@model = @relation.klass
|
|
22
|
+
end
|
|
23
|
+
@table = @model.arel_table if @model.respond_to?(:arel_table)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def call
|
|
27
|
+
self.class._parameters.each do |param|
|
|
28
|
+
value = fetch_criteria(param.name)
|
|
29
|
+
if value.present? || param.allow_blank?
|
|
30
|
+
merge_relation!(send(param.name, value))
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
@relation
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def fetch_criteria(name)
|
|
38
|
+
if @criteria.respond_to?(:fetch)
|
|
39
|
+
@criteria.fetch(name, nil)
|
|
40
|
+
elsif @criteria.respond_to?(name)
|
|
41
|
+
@criteria.send(name)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def merge_relation!(relation)
|
|
46
|
+
if relation.respond_to?(:merge) && Config.merge_relation
|
|
47
|
+
@relation = @relation.merge(relation)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
class_methods do
|
|
52
|
+
def call(*args)
|
|
53
|
+
new(*args).call
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module IIFinder
|
|
4
|
+
class LogSubscriber < ActiveSupport::LogSubscriber
|
|
5
|
+
def call(event)
|
|
6
|
+
debug do
|
|
7
|
+
finder = event.payload[:finder]
|
|
8
|
+
"Called #{finder.class} with #{finder.criteria} (#{additional_log(event)})"
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def additional_log(event)
|
|
13
|
+
additions = ["Duration: %.1fms" % event.duration]
|
|
14
|
+
additions << "Allocations: %d" % event.allocations if event.respond_to?(:allocations)
|
|
15
|
+
additions.join(', ')
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/lib/ii_finder/lookup.rb
CHANGED
|
@@ -19,13 +19,13 @@ module IIFinder
|
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
class << self
|
|
22
|
-
class_attribute :
|
|
23
|
-
self.
|
|
22
|
+
class_attribute :cache
|
|
23
|
+
self.cache = {}
|
|
24
24
|
|
|
25
25
|
def call(klass)
|
|
26
26
|
return if terminate?(klass)
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
with_cache(klass) do
|
|
29
29
|
if klass.name && (resolved = resolve(klass))
|
|
30
30
|
resolved
|
|
31
31
|
elsif klass.superclass
|
|
@@ -36,9 +36,9 @@ module IIFinder
|
|
|
36
36
|
|
|
37
37
|
private
|
|
38
38
|
|
|
39
|
-
def
|
|
39
|
+
def with_cache(klass)
|
|
40
40
|
if Config.lookup_cache
|
|
41
|
-
self.
|
|
41
|
+
self.cache[klass] ||= yield
|
|
42
42
|
else
|
|
43
43
|
yield
|
|
44
44
|
end
|
data/lib/ii_finder/version.rb
CHANGED
data/lib/ii_finder.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ii_finder
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yoshikazu Kaneta
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-
|
|
11
|
+
date: 2021-11-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -120,8 +120,12 @@ files:
|
|
|
120
120
|
- lib/ii_finder.rb
|
|
121
121
|
- lib/ii_finder/base.rb
|
|
122
122
|
- lib/ii_finder/callbacks.rb
|
|
123
|
+
- lib/ii_finder/chain.rb
|
|
123
124
|
- lib/ii_finder/config.rb
|
|
125
|
+
- lib/ii_finder/core.rb
|
|
124
126
|
- lib/ii_finder/errors.rb
|
|
127
|
+
- lib/ii_finder/instrumentation.rb
|
|
128
|
+
- lib/ii_finder/log_subscriber.rb
|
|
125
129
|
- lib/ii_finder/lookup.rb
|
|
126
130
|
- lib/ii_finder/parameter.rb
|
|
127
131
|
- lib/ii_finder/parameters.rb
|