sexy_scopes 0.8.0 → 1.0.0.beta1
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 +13 -0
- data/CONTRIBUTING.md +47 -0
- data/README.md +55 -21
- data/lib/arel/visitors_extensions.rb +19 -50
- data/lib/sexy_scopes.rb +3 -7
- data/lib/sexy_scopes/active_record.rb +3 -0
- data/lib/sexy_scopes/active_record/query_methods.rb +36 -5
- data/lib/sexy_scopes/arel/math.rb +1 -1
- data/lib/sexy_scopes/version.rb +4 -3
- metadata +15 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b42939a28bfedb23b35b8d097662a57daecfb10
|
4
|
+
data.tar.gz: b68a65eba99c7816b27ac9ea56d8af4db8af33f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21c6566a6ee33cfcda27e03555b219c60de5eb70de9ec688a71f5ca1618c4cae154c185f3c9fcf50518ed7d8bc9174d26b7170aefff1d181e9f2a315d45e8a3f
|
7
|
+
data.tar.gz: 713d10f8ab03c8a7b600c2f1d96c19fcc29ce89d8eea7188dd62b3cc60e3b956fd676c68d2f045b610a7a720b9a99cbf0b0d88479d07d3635b78c6ffee0e8339
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,19 @@
|
|
1
1
|
# Changelog
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
+
## 1.0.0.beta1 - 2017-09-17
|
5
|
+
|
6
|
+
### Added
|
7
|
+
- Support for ActiveRecord 5
|
8
|
+
- Support for Ruby >= 2.2
|
9
|
+
- Support for Rubinius 3
|
10
|
+
- Alternative `where` syntax not implemented using `instance_exec` (relation is passed when block takes an argument)
|
11
|
+
- Support for block syntax with `where.not`
|
12
|
+
|
13
|
+
### Removed
|
14
|
+
- Support for ActiveRecord < 4.2
|
15
|
+
- Support for Ruby 1.9.3
|
16
|
+
|
4
17
|
## 0.8.0 - 2015-01-18
|
5
18
|
|
6
19
|
### Added
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
Contributing
|
2
|
+
------------
|
3
|
+
|
4
|
+
### Setup a development environment
|
5
|
+
|
6
|
+
- Create the database config file from the sample:
|
7
|
+
|
8
|
+
cp spec/config.example.yml spec/config.yml
|
9
|
+
|
10
|
+
- Install the required gems:
|
11
|
+
|
12
|
+
bundle install
|
13
|
+
bundle exec appraisal install
|
14
|
+
|
15
|
+
- Edit `spec/config.yml` to reflect the configuration of all your database adapters (similar to `database.yml`)
|
16
|
+
|
17
|
+
- To run the test suite, do:
|
18
|
+
|
19
|
+
bundle exec rake
|
20
|
+
|
21
|
+
- By default, this will only run the tests with the latest version of ActiveRecord and using an in-memory SQLite3 database.
|
22
|
+
This is the simplest way to ensure you've not broken anything.
|
23
|
+
|
24
|
+
- If you want to run the test suite using a particular database, do:
|
25
|
+
|
26
|
+
bundle exec rake spec:mysql
|
27
|
+
bundle exec rake spec:postgresql
|
28
|
+
|
29
|
+
- Before committing your changes, ensure they're compatible with all adapters, *and* all ActiveRecord versions by running:
|
30
|
+
|
31
|
+
bundle exec appraisal rake spec:all
|
32
|
+
|
33
|
+
### Working with GitHub
|
34
|
+
|
35
|
+
Report bugs or suggest features using [GitHub issues](https://github.com/samleb/sexy_scopes).
|
36
|
+
|
37
|
+
1. Fork it
|
38
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
39
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
40
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
41
|
+
5. Create new Pull Request
|
42
|
+
|
43
|
+
TODO
|
44
|
+
----
|
45
|
+
|
46
|
+
- Document the `sql_literal` method and how it can be used to create complex subqueries
|
47
|
+
- Handle associations (i.e. `Post.comments == Comment.joins(:posts)` ?)
|
data/README.md
CHANGED
@@ -13,7 +13,7 @@ SexyScopes is a gem that adds syntactic sugar for creating ActiveRecord scopes
|
|
13
13
|
in Ruby instead of SQL.
|
14
14
|
This allows for more expressive, less error-prone and database independent conditions.
|
15
15
|
|
16
|
-
**WARNING**: This gem requires Ruby >=
|
16
|
+
**WARNING**: This gem requires Ruby >= 2.0.0 and ActiveRecord >= 4.2
|
17
17
|
|
18
18
|
* [Source Code](https://github.com/samleb/sexy_scopes)
|
19
19
|
* [Rubygem](http://rubygems.org/gems/sexy_scopes)
|
@@ -58,12 +58,14 @@ Let's take a look at another example with these relations:
|
|
58
58
|
|
59
59
|
```ruby
|
60
60
|
# rating: integer
|
61
|
+
# body: text
|
61
62
|
class Post < ActiveRecord::Base
|
62
63
|
has_many :comments
|
63
64
|
end
|
64
65
|
|
65
66
|
# post_id: integer
|
66
67
|
# rating: integer
|
68
|
+
# body: text
|
67
69
|
class Comment < ActiveRecord::Base
|
68
70
|
belongs_to :post
|
69
71
|
end
|
@@ -75,7 +77,12 @@ Now let's find posts having comments with a rating greater than a given rating i
|
|
75
77
|
|
76
78
|
```ruby
|
77
79
|
@posts = Post.joins(:comments).where('rating > ?', params[:rating])
|
78
|
-
|
80
|
+
```
|
81
|
+
|
82
|
+
This expression, while syntactically valid, raises the following exception:
|
83
|
+
|
84
|
+
```
|
85
|
+
ActiveRecord::StatementInvalid: ambiguous column name: rating
|
79
86
|
```
|
80
87
|
|
81
88
|
Because both `Post` and `Comment` have a `rating` column, you have to give the table name explicitly:
|
@@ -84,12 +91,12 @@ Because both `Post` and `Comment` have a `rating` column, you have to give the t
|
|
84
91
|
@posts = Post.joins(:comments).where('comments.rating > ?', params[:rating])
|
85
92
|
```
|
86
93
|
|
87
|
-
Not very DRY, is it?
|
88
|
-
|
89
94
|
**With SexyScopes**
|
90
95
|
|
96
|
+
Since `Comment.rating` represents the `rating` column of the `Comment` model, the above can be rewritten as such:
|
97
|
+
|
91
98
|
```ruby
|
92
|
-
@posts = Post.joins(:comments).where
|
99
|
+
@posts = Post.joins(:comments).where { rating > params[:rating] }
|
93
100
|
```
|
94
101
|
|
95
102
|
Here you have it, clear as day, still protected from SQL injection.
|
@@ -145,6 +152,42 @@ Here is a complete list of operators, and their `Arel::Attribute` equivalents:
|
|
145
152
|
- `|`: `or`
|
146
153
|
- `~`: `not`
|
147
154
|
|
155
|
+
Block syntax
|
156
|
+
------------
|
157
|
+
|
158
|
+
SexyScopes introduces a new block syntax for the `where` clause, which can be used in 2 different forms:
|
159
|
+
|
160
|
+
* With no argument, the block is evaluated in the context of the relation
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
# `price` is `Product.price`
|
164
|
+
Product.where { price < 500 }
|
165
|
+
|
166
|
+
# `body` is `post.comments.body`
|
167
|
+
post.comments.where { body =~ "%ruby%" }
|
168
|
+
```
|
169
|
+
|
170
|
+
* With an argument, block is called with the relation as argument
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
# `p` is the `Product` relation
|
174
|
+
Product.where { |p| p.price < 500 }
|
175
|
+
|
176
|
+
# `c` is the `post.comments` relation
|
177
|
+
post.comments.where { |c| c.body =~ "%ruby%" }
|
178
|
+
```
|
179
|
+
|
180
|
+
These 2 forms are functionally equivalent.
|
181
|
+
The former, while being more concise, is internally implemented using `instance_eval`, which will prevent you from calling method on the receiver (`self`).
|
182
|
+
|
183
|
+
*Tip*: Try switching to the later form if you encounter `NoMethodError` exceptions.
|
184
|
+
|
185
|
+
Note that you can also use this syntax with `where.not`:
|
186
|
+
|
187
|
+
```ruby
|
188
|
+
Product.where.not { price > 200 }
|
189
|
+
```
|
190
|
+
|
148
191
|
Regular Expressions
|
149
192
|
-------------------
|
150
193
|
|
@@ -176,7 +219,8 @@ you could do it:
|
|
176
219
|
```ruby
|
177
220
|
class Admin::UsersController
|
178
221
|
def index
|
179
|
-
|
222
|
+
query = Regexp.compile(params[:query])
|
223
|
+
@users = User.where { username =~ query }
|
180
224
|
respond_with @users
|
181
225
|
end
|
182
226
|
end
|
@@ -210,9 +254,9 @@ class Circle < ActiveRecord::Base
|
|
210
254
|
end
|
211
255
|
end
|
212
256
|
|
213
|
-
Circle.where
|
257
|
+
Circle.where { perimeter > 42 }
|
214
258
|
# SQL: SELECT `circles`.* FROM `circles` WHERE (6.283185307179586 * `circles`.`radius` > 42)
|
215
|
-
Circle.where
|
259
|
+
Circle.where { area < 42 }
|
216
260
|
# SQL: SELECT `circles`.* FROM `circles` WHERE (3.141592653589793 * `circles`.`radius` * `circles`.`radius` < 42)
|
217
261
|
|
218
262
|
class Product < ActiveRecord::Base
|
@@ -229,23 +273,13 @@ end
|
|
229
273
|
Contributing
|
230
274
|
------------
|
231
275
|
|
232
|
-
|
233
|
-
|
234
|
-
1. Fork it
|
235
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
236
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
237
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
238
|
-
5. Create new Pull Request
|
239
|
-
|
240
|
-
TODO
|
241
|
-
----
|
276
|
+
All suggestions, ideas and contributions are very welcome.
|
242
277
|
|
243
|
-
|
244
|
-
- Handle associations (i.e. `Post.comments == Comment.joins(:posts)` ?)
|
278
|
+
If you want to contribute, please follow the steps described in [CONTRIBUTING.md](CONTRIBUTING.md)
|
245
279
|
|
246
280
|
Copyright
|
247
281
|
---------
|
248
282
|
|
249
283
|
SexyScopes is released under the [MIT License](http://www.opensource.org/licenses/MIT).
|
250
284
|
|
251
|
-
Copyright (c) 2010-
|
285
|
+
Copyright (c) 2010-2017 Samuel Lebeau, See LICENSE for details.
|
@@ -2,87 +2,56 @@ require 'arel/visitors'
|
|
2
2
|
|
3
3
|
module Arel
|
4
4
|
module Visitors
|
5
|
+
# TODO: Extract these methods into modules
|
5
6
|
class ToSql
|
6
7
|
private
|
7
8
|
|
8
|
-
def visit_Regexp(regexp,
|
9
|
+
def visit_Regexp(regexp, collector)
|
9
10
|
source = SexyScopes.quote(regexp.source)
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
# Arel >= 4.0
|
14
|
-
if instance_method(:visit).arity > 1
|
15
|
-
alias_method :sexy_scopes_visit, :visit
|
16
|
-
else
|
17
|
-
def sexy_scopes_visit(node, arg = nil)
|
18
|
-
visit(node)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
# Arel >= 6.0
|
23
|
-
if instance_method(:accept).arity > 1
|
24
|
-
def reduce_visitor?
|
25
|
-
true
|
26
|
-
end
|
27
|
-
else
|
28
|
-
def reduce_visitor?
|
29
|
-
false
|
30
|
-
end
|
11
|
+
visit source, collector
|
31
12
|
end
|
32
13
|
end
|
33
14
|
|
34
15
|
class MySQL
|
35
16
|
private
|
36
17
|
|
37
|
-
def visit_SexyScopes_Arel_Nodes_RegexpMatches(o,
|
18
|
+
def visit_SexyScopes_Arel_Nodes_RegexpMatches(o, collector)
|
38
19
|
regexp = o.right
|
39
20
|
right = SexyScopes.quote(regexp.source)
|
40
21
|
right = Arel::Nodes::Bin.new(right) unless regexp.casefold?
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
visit right, arg
|
45
|
-
else
|
46
|
-
"#{sexy_scopes_visit o.left, arg} REGEXP #{visit right}"
|
47
|
-
end
|
22
|
+
visit o.left, collector
|
23
|
+
collector << ' REGEXP '
|
24
|
+
visit right, collector
|
48
25
|
end
|
49
26
|
end
|
50
27
|
|
51
28
|
class PostgreSQL
|
52
29
|
private
|
53
30
|
|
54
|
-
def visit_SexyScopes_Arel_Nodes_RegexpMatches(o,
|
31
|
+
def visit_SexyScopes_Arel_Nodes_RegexpMatches(o, collector)
|
55
32
|
regexp = o.right
|
56
33
|
operator = regexp.casefold? ? '~*' : '~'
|
57
34
|
right = SexyScopes.quote(regexp.source)
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
visit right, arg
|
62
|
-
else
|
63
|
-
"#{sexy_scopes_visit o.left, arg} #{operator} #{visit right}"
|
64
|
-
end
|
35
|
+
visit o.left, collector
|
36
|
+
collector << SPACE << operator << SPACE
|
37
|
+
visit right, collector
|
65
38
|
end
|
66
39
|
end
|
67
40
|
|
68
41
|
class Oracle
|
69
42
|
private
|
70
43
|
|
71
|
-
def visit_SexyScopes_Arel_Nodes_RegexpMatches(o,
|
44
|
+
def visit_SexyScopes_Arel_Nodes_RegexpMatches(o, collector)
|
72
45
|
regexp = o.right
|
73
46
|
flags = regexp.casefold? ? 'i' : 'c'
|
74
47
|
flags << 'm' if regexp.options & Regexp::MULTILINE == Regexp::MULTILINE
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
arg << ')'
|
83
|
-
else
|
84
|
-
"REGEXP_LIKE(#{sexy_scopes_visit o.left, arg}, #{visit regexp.source}, #{visit flags})"
|
85
|
-
end
|
48
|
+
collector << 'REGEXP_LIKE('
|
49
|
+
visit o.left, collector
|
50
|
+
collector << COMMA
|
51
|
+
visit regexp.source, collector
|
52
|
+
collector << COMMA
|
53
|
+
visit flags, collector
|
54
|
+
collector << ')'
|
86
55
|
end
|
87
56
|
end
|
88
57
|
end
|
data/lib/sexy_scopes.rb
CHANGED
@@ -13,16 +13,12 @@ module SexyScopes
|
|
13
13
|
predicate.extend(Arel::PredicateMethods)
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
17
|
-
@
|
16
|
+
def arel_9?
|
17
|
+
@arel_9 ||= ::Arel::VERSION >= '9.0.0'
|
18
18
|
end
|
19
19
|
|
20
20
|
def quote(node, attribute = nil)
|
21
|
-
|
22
|
-
::Arel::Nodes.build_quoted(node, attribute)
|
23
|
-
else
|
24
|
-
node
|
25
|
-
end
|
21
|
+
::Arel::Nodes.build_quoted(node, attribute)
|
26
22
|
end
|
27
23
|
|
28
24
|
alias_method :type_cast, :quote
|
@@ -4,4 +4,7 @@ require 'sexy_scopes/active_record/query_methods'
|
|
4
4
|
|
5
5
|
ActiveRecord::Base.extend SexyScopes::ActiveRecord::ClassMethods
|
6
6
|
ActiveRecord::Base.extend SexyScopes::ActiveRecord::DynamicMethods
|
7
|
+
|
7
8
|
ActiveRecord::Relation.send(:include, SexyScopes::ActiveRecord::QueryMethods)
|
9
|
+
|
10
|
+
ActiveRecord::QueryMethods::WhereChain.send(:prepend, SexyScopes::ActiveRecord::QueryMethods::WhereChainMethods)
|
@@ -4,9 +4,9 @@ module SexyScopes
|
|
4
4
|
# Adds support for blocks to ActiveRecord `where`.
|
5
5
|
#
|
6
6
|
# @example
|
7
|
-
# User.where { username
|
7
|
+
# User.where { username =~ 'bob%' }
|
8
8
|
# # is equivalent to:
|
9
|
-
# User.where(User.username
|
9
|
+
# User.where(User.username =~ 'bob%')
|
10
10
|
#
|
11
11
|
# The block is evaluated in the context of the current relation, and the resulting expression
|
12
12
|
# is used as an argument to `where`, thus allowing a cleaner syntax where you don't have to write
|
@@ -21,15 +21,46 @@ module SexyScopes
|
|
21
21
|
#
|
22
22
|
# @raise [ArgumentError] if both arguments and a block are passed
|
23
23
|
#
|
24
|
+
# @see WhereChainMethods#not
|
25
|
+
#
|
24
26
|
def where(*args, &block)
|
25
27
|
if block
|
26
|
-
|
27
|
-
conditions = instance_exec(&block)
|
28
|
-
super(conditions)
|
28
|
+
super(sexy_scopes_build_conditions_from_block(args, block))
|
29
29
|
else
|
30
30
|
super
|
31
31
|
end
|
32
32
|
end
|
33
|
+
|
34
|
+
protected
|
35
|
+
|
36
|
+
def sexy_scopes_build_conditions_from_block(args, block)
|
37
|
+
raise ArgumentError, "You can't use both arguments and a block" if args.any?
|
38
|
+
if block.arity.zero?
|
39
|
+
instance_eval(&block)
|
40
|
+
else
|
41
|
+
block.call(self)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module WhereChainMethods
|
46
|
+
# Adds support for blocks to ActiveRecord `where.not`.
|
47
|
+
#
|
48
|
+
# @example
|
49
|
+
# User.where.not { username =~ 'bob%' }
|
50
|
+
#
|
51
|
+
# @raise [ArgumentError] if both arguments and a block are passed
|
52
|
+
#
|
53
|
+
# @see QueryMethods#where
|
54
|
+
#
|
55
|
+
def not(*args, &block)
|
56
|
+
if block
|
57
|
+
conditions = @scope.send(:sexy_scopes_build_conditions_from_block, args, block)
|
58
|
+
@scope.where(conditions.not)
|
59
|
+
else
|
60
|
+
super
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
33
64
|
end
|
34
65
|
end
|
35
66
|
end
|
data/lib/sexy_scopes/version.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
module SexyScopes
|
2
2
|
module Version
|
3
|
-
MAJOR =
|
4
|
-
MINOR =
|
3
|
+
MAJOR = 1
|
4
|
+
MINOR = 0
|
5
5
|
TINY = 0
|
6
|
+
PRE = 'beta1'
|
6
7
|
|
7
|
-
STRING = [MAJOR, MINOR, TINY].join('.')
|
8
|
+
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
8
9
|
|
9
10
|
class << self
|
10
11
|
# Allows {Version} to display ({to_s}) and behave ({to_str}) as a string
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sexy_scopes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Lebeau
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,34 +16,34 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '4.0'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '5'
|
22
|
+
version: '5.2'
|
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
|
-
version: '
|
29
|
+
version: '4.0'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '5'
|
32
|
+
version: '5.2'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: appraisal
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
37
|
- - "~>"
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: '1
|
39
|
+
version: '2.1'
|
40
40
|
type: :development
|
41
41
|
prerelease: false
|
42
42
|
version_requirements: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '1
|
46
|
+
version: '2.1'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: bundler
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -106,14 +106,14 @@ dependencies:
|
|
106
106
|
requirements:
|
107
107
|
- - "~>"
|
108
108
|
- !ruby/object:Gem::Version
|
109
|
-
version:
|
109
|
+
version: 0.4.9
|
110
110
|
type: :development
|
111
111
|
prerelease: false
|
112
112
|
version_requirements: !ruby/object:Gem::Requirement
|
113
113
|
requirements:
|
114
114
|
- - "~>"
|
115
115
|
- !ruby/object:Gem::Version
|
116
|
-
version:
|
116
|
+
version: 0.4.9
|
117
117
|
- !ruby/object:Gem::Dependency
|
118
118
|
name: pg
|
119
119
|
requirement: !ruby/object:Gem::Requirement
|
@@ -178,6 +178,7 @@ extensions: []
|
|
178
178
|
extra_rdoc_files: []
|
179
179
|
files:
|
180
180
|
- CHANGELOG.md
|
181
|
+
- CONTRIBUTING.md
|
181
182
|
- LICENSE
|
182
183
|
- README.md
|
183
184
|
- lib/arel/visitors_extensions.rb
|
@@ -207,17 +208,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
207
208
|
requirements:
|
208
209
|
- - ">="
|
209
210
|
- !ruby/object:Gem::Version
|
210
|
-
version:
|
211
|
+
version: 2.0.0
|
211
212
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
212
213
|
requirements:
|
213
|
-
- - "
|
214
|
+
- - ">"
|
214
215
|
- !ruby/object:Gem::Version
|
215
|
-
version:
|
216
|
+
version: 1.3.1
|
216
217
|
requirements: []
|
217
218
|
rubyforge_project:
|
218
|
-
rubygems_version: 2.
|
219
|
+
rubygems_version: 2.6.8
|
219
220
|
signing_key:
|
220
221
|
specification_version: 4
|
221
222
|
summary: Write beautiful and expressive ActiveRecord scopes without SQL.
|
222
223
|
test_files: []
|
223
|
-
has_rdoc:
|