sexy_scopes 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/CHANGELOG.md +14 -4
- data/LICENSE +1 -1
- data/README.md +66 -67
- data/lib/arel/visitors_extensions.rb +9 -9
- data/lib/sexy_scopes.rb +9 -13
- data/lib/sexy_scopes/active_record.rb +2 -0
- data/lib/sexy_scopes/active_record/dynamic_methods.rb +6 -6
- data/lib/sexy_scopes/active_record/query_methods.rb +35 -0
- data/lib/sexy_scopes/arel.rb +2 -2
- data/lib/sexy_scopes/arel/math.rb +5 -5
- data/lib/sexy_scopes/arel/predicate_methods.rb +4 -4
- data/lib/sexy_scopes/arel/predications.rb +12 -12
- data/lib/sexy_scopes/arel/typecasting.rb +3 -3
- data/lib/sexy_scopes/version.rb +4 -4
- metadata +41 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a8538efe07dea982f302925e0e126c6dd04680d
|
4
|
+
data.tar.gz: 5d5de790bf16294721550ab1166938b3ad01047a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 95337a57c0814a748d3053174028c0d735798694cc1ca3af048c33d97f79997fa819d7876a44299ba23fabada0601c7a674a93ca0ec8f88ce2d216b472adfc97
|
7
|
+
data.tar.gz: 5a65f9b79859ced79a5bf51f4181464e6402e8e0d2fa1f20f96bda160ebfc2917a2d574d38ca205a564200ddd018891aca0339514ac7e89bad4b390019e5e43c
|
data/CHANGELOG.md
CHANGED
@@ -1,16 +1,26 @@
|
|
1
1
|
# Changelog
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
+
## 0.8.0 - 2015-01-18
|
5
|
+
|
6
|
+
### Added
|
7
|
+
- Support for ActiveRecord 4.2 (thanks to Thomas Kriechbaumer)
|
8
|
+
- Support for blocks in `where`
|
9
|
+
|
10
|
+
### Fixed
|
11
|
+
- Arel no longer needs to be required before SexyScopes
|
12
|
+
|
4
13
|
## 0.7.0 - 2014-07-23
|
5
14
|
|
15
|
+
### Fixed
|
16
|
+
- Existing class methods no longer overriden by dynamic method generation
|
17
|
+
|
6
18
|
### Added
|
7
19
|
- Support for Regular Expressions with the `=~` and `!~` operators (PostgreSQL, MySQL & SQLite3)
|
8
20
|
- Support for ActiveRecord 4.1
|
9
21
|
- Support for Arel 6
|
10
|
-
-
|
11
|
-
|
12
|
-
### Fixed
|
13
|
-
- Existing class methods no longer overriden by dynamic method generation
|
22
|
+
- Typecasting of predicates values to target columns' types
|
23
|
+
- Integration with [Travis CI](https://travis-ci.org/samleb/sexy_scopes)
|
14
24
|
|
15
25
|
### Removed
|
16
26
|
- Support for Ruby 1.9.2
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -27,7 +27,6 @@ Let's define a `Product` model with this schema:
|
|
27
27
|
```ruby
|
28
28
|
# price :integer
|
29
29
|
# category :string
|
30
|
-
# visible :boolean
|
31
30
|
# draft :boolean
|
32
31
|
class Product < ActiveRecord::Base
|
33
32
|
end
|
@@ -36,7 +35,7 @@ end
|
|
36
35
|
Now take a look at the following scope:
|
37
36
|
|
38
37
|
```ruby
|
39
|
-
scope :visible, where(
|
38
|
+
scope :visible, -> { where('category IS NOT NULL AND draft = ? AND price > 0', false) }
|
40
39
|
```
|
41
40
|
|
42
41
|
Hum, lots of *SQL*, not very *Ruby*-esque...
|
@@ -44,7 +43,7 @@ Hum, lots of *SQL*, not very *Ruby*-esque...
|
|
44
43
|
**With SexyScopes**
|
45
44
|
|
46
45
|
```ruby
|
47
|
-
scope :visible, where((category != nil) & (draft == false) & (price > 0))
|
46
|
+
scope :visible, -> { where((category != nil) & (draft == false) & (price > 0)) }
|
48
47
|
```
|
49
48
|
|
50
49
|
Much better! Looks like magic? *It's not*.
|
@@ -70,30 +69,49 @@ class Comment < ActiveRecord::Base
|
|
70
69
|
end
|
71
70
|
```
|
72
71
|
|
73
|
-
Now let's find posts having comments with a rating
|
72
|
+
Now let's find posts having comments with a rating greater than a given rating in a controller action:
|
74
73
|
|
75
74
|
**Without SexyScopes**
|
76
75
|
|
77
76
|
```ruby
|
78
|
-
Post.joins(:comments).
|
77
|
+
@posts = Post.joins(:comments).where('rating > ?', params[:rating])
|
79
78
|
# ActiveRecord::StatementInvalid: ambiguous column name: rating
|
80
79
|
```
|
81
80
|
|
82
81
|
Because both `Post` and `Comment` have a `rating` column, you have to give the table name explicitly:
|
83
82
|
|
84
83
|
```ruby
|
85
|
-
Post.joins(:comments).
|
84
|
+
@posts = Post.joins(:comments).where('comments.rating > ?', params[:rating])
|
86
85
|
```
|
87
86
|
|
88
|
-
Not very DRY,
|
87
|
+
Not very DRY, is it?
|
89
88
|
|
90
89
|
**With SexyScopes**
|
91
90
|
|
92
91
|
```ruby
|
93
|
-
Post.joins(:comments).where Comment.rating >
|
92
|
+
@posts = Post.joins(:comments).where Comment.rating > params[:rating]
|
94
93
|
```
|
95
94
|
|
96
|
-
Here you have it, clear as day.
|
95
|
+
Here you have it, clear as day, still protected from SQL injection.
|
96
|
+
|
97
|
+
Installation
|
98
|
+
------------
|
99
|
+
|
100
|
+
Add this line to your application's Gemfile:
|
101
|
+
|
102
|
+
gem 'sexy_scopes'
|
103
|
+
|
104
|
+
And then execute:
|
105
|
+
|
106
|
+
bundle
|
107
|
+
|
108
|
+
Or install it yourself as:
|
109
|
+
|
110
|
+
gem install sexy_scopes
|
111
|
+
|
112
|
+
Then require it in your application code:
|
113
|
+
|
114
|
+
require 'sexy_scopes'
|
97
115
|
|
98
116
|
How does it work ?
|
99
117
|
------------------
|
@@ -104,15 +122,15 @@ It introduces a `ActiveRecord::Base.attribute(name)` class method returning an `
|
|
104
122
|
represent a table column with the given name, that is extended to support Ruby operators.
|
105
123
|
|
106
124
|
For convenience, SexyScopes dynamically resolves methods whose name is an existing table column: i.e.
|
107
|
-
`Product.price` is
|
125
|
+
`Product.price` is a shortcut for `Product.attribute(:price)`.
|
108
126
|
|
109
127
|
Please note that this mechanism won't override any of the existing `ActiveRecord::Base` class methods,
|
110
128
|
so if you have a column named `name` for instance, you'll have to use `Product.attribute(:name)` instead of
|
111
|
-
`Product.name` (which
|
129
|
+
`Product.name` (which would be in this case the class actual name, `"Product"`).
|
112
130
|
|
113
131
|
Here is a complete list of operators, and their `Arel::Attribute` equivalents:
|
114
132
|
|
115
|
-
*
|
133
|
+
* Predicates:
|
116
134
|
- `==`: `eq`
|
117
135
|
- `=~`: `matches`
|
118
136
|
- `!~`: `does_not_match`
|
@@ -122,61 +140,10 @@ Here is a complete list of operators, and their `Arel::Attribute` equivalents:
|
|
122
140
|
- `<=`: `lteq`
|
123
141
|
- `!=`: `not_eq`
|
124
142
|
|
125
|
-
*
|
143
|
+
* Logical operators:
|
126
144
|
- `&`: `and`
|
127
145
|
- `|`: `or`
|
128
|
-
- `~`: `not`
|
129
|
-
|
130
|
-
Advanced Examples
|
131
|
-
-----------------
|
132
|
-
|
133
|
-
```ruby
|
134
|
-
# radius: integer
|
135
|
-
class Circle < ActiveRecord::Base
|
136
|
-
# Attributes can be coerced in arithmetic operations
|
137
|
-
def self.perimeter
|
138
|
-
2 * Math::PI * radius
|
139
|
-
end
|
140
|
-
|
141
|
-
def self.area
|
142
|
-
Math::PI * radius * radius
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
Circle.where Circle.perimeter > 42
|
147
|
-
# SQL: SELECT `circles`.* FROM `circles` WHERE (6.283185307179586 * `circles`.`radius` > 42)
|
148
|
-
Circle.where Circle.area < 42
|
149
|
-
# SQL: SELECT `circles`.* FROM `circles` WHERE (3.141592653589793 * `circles`.`radius` * `circles`.`radius` < 42)
|
150
|
-
|
151
|
-
class Product < ActiveRecord::Base
|
152
|
-
predicate = (attribute(:name) == nil) & ~category.in(%w( shoes shirts ))
|
153
|
-
puts predicate.to_sql
|
154
|
-
# `products`.`name` IS NULL AND NOT (`products`.`category` IN ('shoes', 'shirts'))
|
155
|
-
|
156
|
-
where(predicate).all
|
157
|
-
# SQL: SELECT `products`.* FROM `products` WHERE `products`.`name` IS NULL AND
|
158
|
-
# NOT (`products`.`category` IN ('shoes', 'shirts'))
|
159
|
-
end
|
160
|
-
```
|
161
|
-
|
162
|
-
Installation
|
163
|
-
------------
|
164
|
-
|
165
|
-
Add this line to your application's Gemfile:
|
166
|
-
|
167
|
-
gem 'sexy_scopes'
|
168
|
-
|
169
|
-
And then execute:
|
170
|
-
|
171
|
-
bundle
|
172
|
-
|
173
|
-
Or install it yourself as:
|
174
|
-
|
175
|
-
gem install sexy_scopes
|
176
|
-
|
177
|
-
Then require it in your application code:
|
178
|
-
|
179
|
-
require 'sexy_scopes'
|
146
|
+
- `~`: `not`
|
180
147
|
|
181
148
|
Regular Expressions
|
182
149
|
-------------------
|
@@ -224,9 +191,41 @@ Started GET "/admin/users?query=bob%7Calice" for xx.xx.xx.xx at 2014-03-31 16:00
|
|
224
191
|
User Load (0.1ms) SELECT "users".* FROM "users" WHERE ("users"."username" ~ 'bob|alice')
|
225
192
|
```
|
226
193
|
|
227
|
-
The proper SQL is generated, protected from SQL injection BTW, and from now on you have reusable code for
|
194
|
+
The proper SQL is generated, protected from SQL injection BTW, and from now on you have reusable code for
|
228
195
|
both you development and your production environment.
|
229
196
|
|
197
|
+
Advanced Examples
|
198
|
+
-----------------
|
199
|
+
|
200
|
+
```ruby
|
201
|
+
# radius: integer
|
202
|
+
class Circle < ActiveRecord::Base
|
203
|
+
# Attributes can be coerced in arithmetic operations
|
204
|
+
def self.perimeter
|
205
|
+
2 * Math::PI * radius
|
206
|
+
end
|
207
|
+
|
208
|
+
def self.area
|
209
|
+
Math::PI * radius * radius
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
Circle.where Circle.perimeter > 42
|
214
|
+
# SQL: SELECT `circles`.* FROM `circles` WHERE (6.283185307179586 * `circles`.`radius` > 42)
|
215
|
+
Circle.where Circle.area < 42
|
216
|
+
# SQL: SELECT `circles`.* FROM `circles` WHERE (3.141592653589793 * `circles`.`radius` * `circles`.`radius` < 42)
|
217
|
+
|
218
|
+
class Product < ActiveRecord::Base
|
219
|
+
predicate = (attribute(:name) == nil) & ~category.in(%w( shoes shirts ))
|
220
|
+
puts predicate.to_sql
|
221
|
+
# `products`.`name` IS NULL AND NOT (`products`.`category` IN ('shoes', 'shirts'))
|
222
|
+
|
223
|
+
where(predicate).all
|
224
|
+
# SQL: SELECT `products`.* FROM `products` WHERE `products`.`name` IS NULL AND
|
225
|
+
# NOT (`products`.`category` IN ('shoes', 'shirts'))
|
226
|
+
end
|
227
|
+
```
|
228
|
+
|
230
229
|
Contributing
|
231
230
|
------------
|
232
231
|
|
@@ -249,4 +248,4 @@ Copyright
|
|
249
248
|
|
250
249
|
SexyScopes is released under the [MIT License](http://www.opensource.org/licenses/MIT).
|
251
250
|
|
252
|
-
Copyright (c) 2010-
|
251
|
+
Copyright (c) 2010-2014 Samuel Lebeau, See LICENSE for details.
|
@@ -4,12 +4,12 @@ module Arel
|
|
4
4
|
module Visitors
|
5
5
|
class ToSql
|
6
6
|
private
|
7
|
-
|
7
|
+
|
8
8
|
def visit_Regexp(regexp, arg = nil)
|
9
9
|
source = SexyScopes.quote(regexp.source)
|
10
10
|
sexy_scopes_visit source, arg
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
# Arel >= 4.0
|
14
14
|
if instance_method(:visit).arity > 1
|
15
15
|
alias_method :sexy_scopes_visit, :visit
|
@@ -18,7 +18,7 @@ module Arel
|
|
18
18
|
visit(node)
|
19
19
|
end
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
# Arel >= 6.0
|
23
23
|
if instance_method(:accept).arity > 1
|
24
24
|
def reduce_visitor?
|
@@ -30,10 +30,10 @@ module Arel
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
class MySQL
|
35
35
|
private
|
36
|
-
|
36
|
+
|
37
37
|
def visit_SexyScopes_Arel_Nodes_RegexpMatches(o, arg = nil)
|
38
38
|
regexp = o.right
|
39
39
|
right = SexyScopes.quote(regexp.source)
|
@@ -47,10 +47,10 @@ module Arel
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
class PostgreSQL
|
52
52
|
private
|
53
|
-
|
53
|
+
|
54
54
|
def visit_SexyScopes_Arel_Nodes_RegexpMatches(o, arg = nil)
|
55
55
|
regexp = o.right
|
56
56
|
operator = regexp.casefold? ? '~*' : '~'
|
@@ -64,10 +64,10 @@ module Arel
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
class Oracle
|
69
69
|
private
|
70
|
-
|
70
|
+
|
71
71
|
def visit_SexyScopes_Arel_Nodes_RegexpMatches(o, arg = nil)
|
72
72
|
regexp = o.right
|
73
73
|
flags = regexp.casefold? ? 'i' : 'c'
|
data/lib/sexy_scopes.rb
CHANGED
@@ -3,32 +3,28 @@ require 'sexy_scopes/version'
|
|
3
3
|
|
4
4
|
module SexyScopes
|
5
5
|
autoload :Arel, 'sexy_scopes/arel'
|
6
|
-
|
6
|
+
|
7
7
|
class << self
|
8
|
-
AREL_6 = ::Arel::VERSION >= '6.0.0'
|
9
|
-
|
10
8
|
def extend_expression(expression)
|
11
9
|
expression.extend(Arel::ExpressionMethods)
|
12
10
|
end
|
13
|
-
|
11
|
+
|
14
12
|
def extend_predicate(predicate)
|
15
13
|
predicate.extend(Arel::PredicateMethods)
|
16
14
|
end
|
17
|
-
|
15
|
+
|
18
16
|
def arel_6?
|
19
|
-
|
17
|
+
@arel_6 ||= ::Arel::VERSION >= '6.0.0'
|
20
18
|
end
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
|
20
|
+
def quote(node, attribute = nil)
|
21
|
+
if arel_6?
|
24
22
|
::Arel::Nodes.build_quoted(node, attribute)
|
25
|
-
|
26
|
-
else
|
27
|
-
def quote(node, attribute = nil)
|
23
|
+
else
|
28
24
|
node
|
29
25
|
end
|
30
26
|
end
|
31
|
-
|
27
|
+
|
32
28
|
alias_method :type_cast, :quote
|
33
29
|
end
|
34
30
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'sexy_scopes/active_record/class_methods'
|
2
2
|
require 'sexy_scopes/active_record/dynamic_methods'
|
3
|
+
require 'sexy_scopes/active_record/query_methods'
|
3
4
|
|
4
5
|
ActiveRecord::Base.extend SexyScopes::ActiveRecord::ClassMethods
|
5
6
|
ActiveRecord::Base.extend SexyScopes::ActiveRecord::DynamicMethods
|
7
|
+
ActiveRecord::Relation.send(:include, SexyScopes::ActiveRecord::QueryMethods)
|
@@ -11,12 +11,12 @@ module SexyScopes
|
|
11
11
|
sexy_scopes_has_attribute?(method_name)
|
12
12
|
end
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
# Equivalent to calling {#attribute} with the missing method's <tt>name</tt> if the table
|
16
16
|
# has a column with that name.
|
17
17
|
#
|
18
18
|
# Delegates to superclass implementation otherwise, eventually raising <tt>NoMethodError</tt>.
|
19
|
-
#
|
19
|
+
#
|
20
20
|
# @see #attribute
|
21
21
|
#
|
22
22
|
# @note Due to the way this works, be careful not to use this syntactic sugar with existing
|
@@ -28,7 +28,7 @@ module SexyScopes
|
|
28
28
|
# # Suppose the "users" table has an "email" column, then these are equivalent:
|
29
29
|
# User.email
|
30
30
|
# User.attribute(:email)
|
31
|
-
#
|
31
|
+
#
|
32
32
|
# @example
|
33
33
|
# # Here is the previous example (from `attribute`) rewritten:
|
34
34
|
# User.where(User.score > 1000)
|
@@ -48,7 +48,7 @@ module SexyScopes
|
|
48
48
|
send(name, *args, &block)
|
49
49
|
end
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
def sexy_scopes_define_attribute_methods
|
53
53
|
@sexy_scopes_attribute_methods_generated = true
|
54
54
|
return unless sexy_scopes_is_table?
|
@@ -58,11 +58,11 @@ module SexyScopes
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
def sexy_scopes_has_attribute?(attribute_name)
|
63
63
|
sexy_scopes_is_table? && column_names.include?(attribute_name.to_s)
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
def sexy_scopes_is_table?
|
67
67
|
!(equal?(::ActiveRecord::Base) || abstract_class?) && table_exists?
|
68
68
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module SexyScopes
|
2
|
+
module ActiveRecord
|
3
|
+
module QueryMethods
|
4
|
+
# Adds support for blocks to ActiveRecord `where`.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# User.where { username == 'bob' }
|
8
|
+
# # is equivalent to:
|
9
|
+
# User.where(User.username == 'bob')
|
10
|
+
#
|
11
|
+
# The block is evaluated in the context of the current relation, and the resulting expression
|
12
|
+
# is used as an argument to `where`, thus allowing a cleaner syntax where you don't have to write
|
13
|
+
# the receiver of the method explicitely, in this case: `username` vs `User.username`
|
14
|
+
#
|
15
|
+
# This form can also be used with relations:
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
# post.comments.where { rating > 5 }
|
19
|
+
# # is equivalent to:
|
20
|
+
# post.comments.where(Comment.rating > 5)
|
21
|
+
#
|
22
|
+
# @raise [ArgumentError] if both arguments and a block are passed
|
23
|
+
#
|
24
|
+
def where(*args, &block)
|
25
|
+
if block
|
26
|
+
raise ArgumentError, "You can't use both arguments and a block" if args.any?
|
27
|
+
conditions = instance_exec(&block)
|
28
|
+
super(conditions)
|
29
|
+
else
|
30
|
+
super
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/sexy_scopes/arel.rb
CHANGED
@@ -4,11 +4,11 @@ module SexyScopes
|
|
4
4
|
module Arel
|
5
5
|
autoload :ExpressionMethods, 'sexy_scopes/arel/expression_methods'
|
6
6
|
autoload :PredicateMethods, 'sexy_scopes/arel/predicate_methods'
|
7
|
-
|
7
|
+
|
8
8
|
autoload :Predications, 'sexy_scopes/arel/predications'
|
9
9
|
autoload :Typecasting, 'sexy_scopes/arel/typecasting'
|
10
10
|
autoload :Math, 'sexy_scopes/arel/math'
|
11
|
-
|
11
|
+
|
12
12
|
module Nodes
|
13
13
|
autoload :RegexpMatches, 'sexy_scopes/arel/nodes/regexp_matches'
|
14
14
|
end
|
@@ -2,23 +2,23 @@ module SexyScopes
|
|
2
2
|
module Arel
|
3
3
|
module Math
|
4
4
|
include Typecasting if SexyScopes.arel_6?
|
5
|
-
|
5
|
+
|
6
6
|
def *(other)
|
7
7
|
SexyScopes.extend_expression(super)
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
def +(other)
|
11
11
|
SexyScopes.extend_expression(super)
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
def -(other)
|
15
15
|
SexyScopes.extend_expression(super)
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
def /(other)
|
19
19
|
SexyScopes.extend_expression(super)
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
def coerce(other)
|
23
23
|
expression = ::Arel.sql(other.to_s)
|
24
24
|
[SexyScopes.extend_expression(expression), self]
|
@@ -1,21 +1,21 @@
|
|
1
1
|
module SexyScopes
|
2
2
|
module Arel
|
3
3
|
module PredicateMethods
|
4
|
-
# <tt>Arel::Grouping</tt> nodes didn't include <tt>Arel::Predications</tt> before Arel 3, but <tt>or</tt>
|
4
|
+
# <tt>Arel::Grouping</tt> nodes didn't include <tt>Arel::Predications</tt> before Arel 3, but <tt>or</tt>
|
5
5
|
# returns an <tt>Arel::Grouping</tt> node (surrounds the SQL <tt>OR</tt> clause with parenthesis).
|
6
6
|
# Since ActiveRecord 3.1 depends on Arel 2, including the module here ensures the methods will exist.
|
7
7
|
include ::Arel::Predications
|
8
|
-
|
8
|
+
|
9
9
|
def not
|
10
10
|
SexyScopes.extend_predicate(super)
|
11
11
|
end
|
12
12
|
alias ~ not
|
13
|
-
|
13
|
+
|
14
14
|
def or(other)
|
15
15
|
SexyScopes.extend_predicate(super)
|
16
16
|
end
|
17
17
|
alias | or
|
18
|
-
|
18
|
+
|
19
19
|
def and(other)
|
20
20
|
SexyScopes.extend_predicate(super)
|
21
21
|
end
|
@@ -5,12 +5,12 @@ module SexyScopes
|
|
5
5
|
SexyScopes.extend_predicate(super)
|
6
6
|
end
|
7
7
|
alias == eq
|
8
|
-
|
8
|
+
|
9
9
|
def in(other)
|
10
10
|
SexyScopes.extend_predicate(super)
|
11
11
|
end
|
12
|
-
|
13
|
-
def matches(other)
|
12
|
+
|
13
|
+
def matches(other, *)
|
14
14
|
if Regexp === other
|
15
15
|
matches_regexp(other)
|
16
16
|
else
|
@@ -18,8 +18,8 @@ module SexyScopes
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
alias =~ matches
|
21
|
-
|
22
|
-
def does_not_match(other)
|
21
|
+
|
22
|
+
def does_not_match(other, *)
|
23
23
|
if Regexp === other
|
24
24
|
does_not_match_regexp(other)
|
25
25
|
else
|
@@ -27,36 +27,36 @@ module SexyScopes
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
alias !~ does_not_match
|
30
|
-
|
30
|
+
|
31
31
|
def matches_regexp(other)
|
32
32
|
predicate = Arel::Nodes::RegexpMatches.new(self, other)
|
33
33
|
SexyScopes.extend_predicate(predicate)
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
def does_not_match_regexp(other)
|
37
37
|
matches_regexp(other).not
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
def gteq(other)
|
41
41
|
SexyScopes.extend_predicate(super)
|
42
42
|
end
|
43
43
|
alias >= gteq
|
44
|
-
|
44
|
+
|
45
45
|
def gt(other)
|
46
46
|
SexyScopes.extend_predicate(super)
|
47
47
|
end
|
48
48
|
alias > gt
|
49
|
-
|
49
|
+
|
50
50
|
def lt(other)
|
51
51
|
SexyScopes.extend_predicate(super)
|
52
52
|
end
|
53
53
|
alias < lt
|
54
|
-
|
54
|
+
|
55
55
|
def lteq(other)
|
56
56
|
SexyScopes.extend_predicate(super)
|
57
57
|
end
|
58
58
|
alias <= lteq
|
59
|
-
|
59
|
+
|
60
60
|
def not_eq(other)
|
61
61
|
SexyScopes.extend_predicate(super)
|
62
62
|
end
|
@@ -4,15 +4,15 @@ module SexyScopes
|
|
4
4
|
def *(other)
|
5
5
|
super SexyScopes.type_cast(other, self)
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
def +(other)
|
9
9
|
super SexyScopes.type_cast(other, self)
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def -(other)
|
13
13
|
super SexyScopes.type_cast(other, self)
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def /(other)
|
17
17
|
super SexyScopes.type_cast(other, self)
|
18
18
|
end
|
data/lib/sexy_scopes/version.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
module SexyScopes
|
2
2
|
module Version
|
3
3
|
MAJOR = 0
|
4
|
-
MINOR =
|
4
|
+
MINOR = 8
|
5
5
|
TINY = 0
|
6
|
-
|
6
|
+
|
7
7
|
STRING = [MAJOR, MINOR, TINY].join('.')
|
8
|
-
|
8
|
+
|
9
9
|
class << self
|
10
10
|
# Allows {Version} to display ({to_s}) and behave ({to_str}) as a string
|
11
11
|
def to_str
|
@@ -14,6 +14,6 @@ module SexyScopes
|
|
14
14
|
alias_method :to_s, :to_str
|
15
15
|
end
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
VERSION = Version::STRING
|
19
19
|
end
|
metadata
CHANGED
@@ -1,167 +1,173 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sexy_scopes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
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: 2015-01-18 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.1'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '5'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- -
|
27
|
+
- - ">="
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: '3.1'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '5'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: appraisal
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
31
|
-
- - ~>
|
37
|
+
- - "~>"
|
32
38
|
- !ruby/object:Gem::Version
|
33
39
|
version: '1.0'
|
34
40
|
type: :development
|
35
41
|
prerelease: false
|
36
42
|
version_requirements: !ruby/object:Gem::Requirement
|
37
43
|
requirements:
|
38
|
-
- - ~>
|
44
|
+
- - "~>"
|
39
45
|
- !ruby/object:Gem::Version
|
40
46
|
version: '1.0'
|
41
47
|
- !ruby/object:Gem::Dependency
|
42
48
|
name: bundler
|
43
49
|
requirement: !ruby/object:Gem::Requirement
|
44
50
|
requirements:
|
45
|
-
- - ~>
|
51
|
+
- - "~>"
|
46
52
|
- !ruby/object:Gem::Version
|
47
53
|
version: '1.0'
|
48
54
|
type: :development
|
49
55
|
prerelease: false
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
51
57
|
requirements:
|
52
|
-
- - ~>
|
58
|
+
- - "~>"
|
53
59
|
- !ruby/object:Gem::Version
|
54
60
|
version: '1.0'
|
55
61
|
- !ruby/object:Gem::Dependency
|
56
62
|
name: rake
|
57
63
|
requirement: !ruby/object:Gem::Requirement
|
58
64
|
requirements:
|
59
|
-
- -
|
65
|
+
- - ">="
|
60
66
|
- !ruby/object:Gem::Version
|
61
67
|
version: '0.9'
|
62
68
|
type: :development
|
63
69
|
prerelease: false
|
64
70
|
version_requirements: !ruby/object:Gem::Requirement
|
65
71
|
requirements:
|
66
|
-
- -
|
72
|
+
- - ">="
|
67
73
|
- !ruby/object:Gem::Version
|
68
74
|
version: '0.9'
|
69
75
|
- !ruby/object:Gem::Dependency
|
70
76
|
name: rspec
|
71
77
|
requirement: !ruby/object:Gem::Requirement
|
72
78
|
requirements:
|
73
|
-
- - ~>
|
79
|
+
- - "~>"
|
74
80
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
81
|
+
version: '3.0'
|
76
82
|
type: :development
|
77
83
|
prerelease: false
|
78
84
|
version_requirements: !ruby/object:Gem::Requirement
|
79
85
|
requirements:
|
80
|
-
- - ~>
|
86
|
+
- - "~>"
|
81
87
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
88
|
+
version: '3.0'
|
83
89
|
- !ruby/object:Gem::Dependency
|
84
90
|
name: sqlite3
|
85
91
|
requirement: !ruby/object:Gem::Requirement
|
86
92
|
requirements:
|
87
|
-
- - ~>
|
93
|
+
- - "~>"
|
88
94
|
- !ruby/object:Gem::Version
|
89
95
|
version: '1.0'
|
90
96
|
type: :development
|
91
97
|
prerelease: false
|
92
98
|
version_requirements: !ruby/object:Gem::Requirement
|
93
99
|
requirements:
|
94
|
-
- - ~>
|
100
|
+
- - "~>"
|
95
101
|
- !ruby/object:Gem::Version
|
96
102
|
version: '1.0'
|
97
103
|
- !ruby/object:Gem::Dependency
|
98
104
|
name: mysql2
|
99
105
|
requirement: !ruby/object:Gem::Requirement
|
100
106
|
requirements:
|
101
|
-
- - ~>
|
107
|
+
- - "~>"
|
102
108
|
- !ruby/object:Gem::Version
|
103
109
|
version: '0.3'
|
104
110
|
type: :development
|
105
111
|
prerelease: false
|
106
112
|
version_requirements: !ruby/object:Gem::Requirement
|
107
113
|
requirements:
|
108
|
-
- - ~>
|
114
|
+
- - "~>"
|
109
115
|
- !ruby/object:Gem::Version
|
110
116
|
version: '0.3'
|
111
117
|
- !ruby/object:Gem::Dependency
|
112
118
|
name: pg
|
113
119
|
requirement: !ruby/object:Gem::Requirement
|
114
120
|
requirements:
|
115
|
-
- - ~>
|
121
|
+
- - "~>"
|
116
122
|
- !ruby/object:Gem::Version
|
117
123
|
version: '0.8'
|
118
124
|
type: :development
|
119
125
|
prerelease: false
|
120
126
|
version_requirements: !ruby/object:Gem::Requirement
|
121
127
|
requirements:
|
122
|
-
- - ~>
|
128
|
+
- - "~>"
|
123
129
|
- !ruby/object:Gem::Version
|
124
130
|
version: '0.8'
|
125
131
|
- !ruby/object:Gem::Dependency
|
126
132
|
name: redcarpet
|
127
133
|
requirement: !ruby/object:Gem::Requirement
|
128
134
|
requirements:
|
129
|
-
- - ~>
|
135
|
+
- - "~>"
|
130
136
|
- !ruby/object:Gem::Version
|
131
137
|
version: '3.0'
|
132
138
|
type: :development
|
133
139
|
prerelease: false
|
134
140
|
version_requirements: !ruby/object:Gem::Requirement
|
135
141
|
requirements:
|
136
|
-
- - ~>
|
142
|
+
- - "~>"
|
137
143
|
- !ruby/object:Gem::Version
|
138
144
|
version: '3.0'
|
139
145
|
- !ruby/object:Gem::Dependency
|
140
146
|
name: yard
|
141
147
|
requirement: !ruby/object:Gem::Requirement
|
142
148
|
requirements:
|
143
|
-
- - ~>
|
149
|
+
- - "~>"
|
144
150
|
- !ruby/object:Gem::Version
|
145
151
|
version: '0.8'
|
146
152
|
type: :development
|
147
153
|
prerelease: false
|
148
154
|
version_requirements: !ruby/object:Gem::Requirement
|
149
155
|
requirements:
|
150
|
-
- - ~>
|
156
|
+
- - "~>"
|
151
157
|
- !ruby/object:Gem::Version
|
152
158
|
version: '0.8'
|
153
159
|
- !ruby/object:Gem::Dependency
|
154
160
|
name: simplecov
|
155
161
|
requirement: !ruby/object:Gem::Requirement
|
156
162
|
requirements:
|
157
|
-
- -
|
163
|
+
- - ">="
|
158
164
|
- !ruby/object:Gem::Version
|
159
165
|
version: '0'
|
160
166
|
type: :development
|
161
167
|
prerelease: false
|
162
168
|
version_requirements: !ruby/object:Gem::Requirement
|
163
169
|
requirements:
|
164
|
-
- -
|
170
|
+
- - ">="
|
165
171
|
- !ruby/object:Gem::Version
|
166
172
|
version: '0'
|
167
173
|
description: Small DSL to create ActiveRecord (>= 3.1) attribute predicates without
|
@@ -172,22 +178,23 @@ extensions: []
|
|
172
178
|
extra_rdoc_files: []
|
173
179
|
files:
|
174
180
|
- CHANGELOG.md
|
175
|
-
- README.md
|
176
181
|
- LICENSE
|
182
|
+
- README.md
|
177
183
|
- lib/arel/visitors_extensions.rb
|
184
|
+
- lib/sexy_scopes.rb
|
185
|
+
- lib/sexy_scopes/active_record.rb
|
178
186
|
- lib/sexy_scopes/active_record/class_methods.rb
|
179
187
|
- lib/sexy_scopes/active_record/dynamic_methods.rb
|
180
|
-
- lib/sexy_scopes/active_record.rb
|
188
|
+
- lib/sexy_scopes/active_record/query_methods.rb
|
189
|
+
- lib/sexy_scopes/arel.rb
|
181
190
|
- lib/sexy_scopes/arel/expression_methods.rb
|
182
191
|
- lib/sexy_scopes/arel/math.rb
|
183
192
|
- lib/sexy_scopes/arel/nodes/regexp_matches.rb
|
184
193
|
- lib/sexy_scopes/arel/predicate_methods.rb
|
185
194
|
- lib/sexy_scopes/arel/predications.rb
|
186
195
|
- lib/sexy_scopes/arel/typecasting.rb
|
187
|
-
- lib/sexy_scopes/arel.rb
|
188
196
|
- lib/sexy_scopes/railtie.rb
|
189
197
|
- lib/sexy_scopes/version.rb
|
190
|
-
- lib/sexy_scopes.rb
|
191
198
|
homepage: https://github.com/samleb/sexy_scopes
|
192
199
|
licenses:
|
193
200
|
- MIT
|
@@ -198,17 +205,17 @@ require_paths:
|
|
198
205
|
- lib
|
199
206
|
required_ruby_version: !ruby/object:Gem::Requirement
|
200
207
|
requirements:
|
201
|
-
- -
|
208
|
+
- - ">="
|
202
209
|
- !ruby/object:Gem::Version
|
203
|
-
version: 1.9.
|
210
|
+
version: 1.9.3
|
204
211
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
205
212
|
requirements:
|
206
|
-
- -
|
213
|
+
- - ">="
|
207
214
|
- !ruby/object:Gem::Version
|
208
215
|
version: '0'
|
209
216
|
requirements: []
|
210
217
|
rubyforge_project:
|
211
|
-
rubygems_version: 2.
|
218
|
+
rubygems_version: 2.2.2
|
212
219
|
signing_key:
|
213
220
|
specification_version: 4
|
214
221
|
summary: Write beautiful and expressive ActiveRecord scopes without SQL.
|