arel-extensions 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3c79633129067dda19ceaeaf6f0241b23d57c804
4
- data.tar.gz: 7f401572e73ed1e40cde5f094360d427bd7539c1
3
+ metadata.gz: ea6bb2f32dc1602cd546c28188fe5ed2be2a0f09
4
+ data.tar.gz: e11ccebf5147a7d83f7e081c17bda2e387aa6b41
5
5
  SHA512:
6
- metadata.gz: d306bc36f6b25224da947efc251686455e7353f67bc9af65ba7f81df704838ff640c0fe5f6d030f5a33cfffbc5e5f51885caba4c715231072463d24582b7a602
7
- data.tar.gz: d802003762477a56fde5f2e7f7b08c4dbbdab73cc0f448d5915a953cdfe8ce5562bb1e7aa785876f8069eda3b1e8487461a8c3aa8488e16293c36cd9487cbd0f
6
+ metadata.gz: dd5bb4101f987f0143643d01437550e141b2867ff5447e9e15164cb0359e44445f15a188bcf72d12ac729602e9f5093dfcaf618c6646dbbc68ca11002e8e6274
7
+ data.tar.gz: 39827c24bc7ed46ee7d2578db388f30d38c00ef489acf98d49929401e5476c33f05aaff91363125dcf420917f643393b68e351675b6bfe6d8df2bd10f567c541
data/README.md CHANGED
@@ -19,198 +19,4 @@ Or install it yourself as:
19
19
  ## Usage
20
20
 
21
21
  Just `require 'arel-extensions'` and use Arel/ActiveRecord as you normally would!
22
- arel-extensions extends ActiveRecord's query methods in both Arel and ActiveRecord.
23
-
24
- * [Querying PostgreSQL datatypes](docs/querying.md)
25
-
26
- ## Arrays
27
-
28
- * [@> - Array Contains operator](#---array-contains-operator)
29
- * [<@ - Array Contained By operator](#---array-contined-by-operator)
30
- * [&& - Array Overlap operator](#---array-overlap-operator)
31
-
32
- ### && - Array Overlap operator
33
-
34
- PostgreSQL implements the `&&` operator, known as the overlap operator,
35
- for arrays. The overlap operator returns `t` (true) when two arrays have
36
- one or more elements in common.
37
-
38
- ```sql
39
- ARRAY[1,2,3] && ARRAY[4,5,6]
40
- -- f
41
-
42
- ARRAY[1,2,3] && ARRAY[3,5,6]
43
- -- t
44
- ```
45
-
46
- Postgres\_ext extends the `ActiveRecord::Relation.where` method similar
47
- to the Rails 4.0 not clause. The easiest way to make a overlap query
48
- would be:
49
-
50
- ```ruby
51
- User.where.overlap(:nick_names => ['Bob', 'Fred'])
52
- ```
53
-
54
- Postgres\_ext defines `overlap`, an [Arel](https://github.com/rails/arel)
55
- predicate for the `&&` operator. This is utilized by the `where.overlap`
56
- call above.
57
-
58
- ```ruby
59
- user_arel = User.arel_table
60
-
61
- # Execute the query
62
- User.where(user_arel[:tags].overlap(['one','two']))
63
- # => SELECT \"users\".* FROM \"users\" WHERE \"users\".\"tags\" && '{one,two}'
64
- ```
65
-
66
- ### @> - Array Contains operator
67
-
68
- PostgreSQL has a contains (`@>`) operator for querying whether all the
69
- elements of an array are within another.
70
-
71
- ```sql
72
- ARRAY[1,2,3] @> ARRAY[3,4]
73
- -- f
74
-
75
- ARRAY[1,2,3] @> ARRAY[2,3]
76
- -- t
77
- ```
78
-
79
- Postgres\_ext extends the `ActiveRecord::Relation.where` method by
80
- adding a `contains` method. To make a contains query, you can do:
81
-
82
- ```ruby
83
- User.where.contains(:nick_names => ['Bob', 'Fred'])
84
- ```
85
-
86
- Postgres\_ext overrides `contains`, an [Arel](https://github.com/rails/arel)
87
- predicate, to use the `@>` operator for arrays. This is utilized by the
88
- `where.contains` call above.
89
-
90
- ```ruby
91
- user_arel = User.arel_table
92
-
93
- # Execute the query
94
- User.where(user_arel[:tags].contains(['one','two']))
95
- # => SELECT "users".* FROM "users" WHERE "users"."tags" @> '{"one","two"}'
96
- ```
97
-
98
- ### ANY or ALL functions
99
-
100
- When querying array columns, you have the ability to see if a predicate
101
- apply's to either *any* element in the array, or *all* elements of the
102
- array. The syntax for these predicates are slightly different then the
103
- normal `where` syntax in PostgreSQL. To see if an array contains the
104
- string `'test'` in any location, you would write the following in SQL
105
-
106
- ```sql
107
- SELECT *
108
- FROM users
109
- WHERE 'test' = ANY(users.tags)
110
- ```
111
-
112
- Notice that the column is on the right hand side of the predicate,
113
- instead of the left, because we have to call the `ANY` function on that
114
- column.
115
-
116
- Postgres\_ext provides a `ActiveRecord::Relation.where.any()` method. The
117
- easiest way to make a ANY query would be:
118
-
119
- ```ruby
120
- User.where.any(:nick_names => 'Bob')
121
- ```
122
-
123
- There is also an `ActiveRecord::Relation.where.all()` call as well. This
124
- method utilizes the following code to create the query:
125
-
126
- We can generate the above query using [Arel](https://github.com/rails/arel)
127
- and generating the Node manually. We would use the following to
128
- accompish this:
129
-
130
- ```ruby
131
- user_arel = User.arel_table
132
-
133
- # Execute the query
134
- User.where(user_arel[:tags].any('test'))
135
- #=> SELECT \"users\".* FROM \"users\" WHERE 'test' = ANY(\"users\".\"tags\")
136
- ```
137
-
138
- The ALL version of this same predicate can be generated by swapping
139
- `#any()` for `#all()`.
140
-
141
- ## INET/CIDR Queries
142
-
143
- PostgreSQL defines the `<<`, or contained within operator for INET and
144
- CIDR datatypes. The `<<` operator returns `t` (true) if a INET or CIDR
145
- address is contained within the given subnet.
146
-
147
- ```sql
148
- inet '192.168.1.6' << inet '10.0.0.0/24'
149
- -- f
150
-
151
- inet '192.168.1.6' << inet '192.168.1.0/24'
152
- -- t
153
- ```
154
-
155
- In addition to contained within, there is also:
156
-
157
- * `<<=` - Contained within or equals
158
- * `>>` - Contains
159
- * `>>=` - Contains or equals
160
-
161
- Postgres\_ext extends the `ActiveRecord::Relation.where` method similar
162
- to the Rails 4.0 not clause. The easiest way to make a overlap query
163
- would be:
164
-
165
- ```ruby
166
- User.where.contained_within(:ip => '192.168.1.1/24')
167
- User.where.contained_within_or_equals(:ip => '192.168.1.1/24')
168
- User.where.contains(:ip => '192.168.1.14')
169
- User.where.contains_or_equals(:ip => '192.168.1.14')
170
- ```
171
-
172
- Postgres\_ext defines `contained_within`, an [Arel](https://github.com/rails/arel)
173
- predicate for the `<<` operator. This is utilized by the
174
- methods above.
175
-
176
- ```ruby
177
- user_arel = User.arel_table
178
-
179
- # Execute the query
180
- User.where(user_arel[:ip_address].contained_within('127.0.0.1/24'))
181
- # => SELECT \"users\".* FROM \"users\" WHERE \"users\".\"ip_address\" << '127.0.0.1/24'
182
- User.where(user_arel[:ip_address].contained_within_or_equals('127.0.0.1/24'))
183
- # => SELECT \"users\".* FROM \"users\" WHERE \"users\".\"ip_address\" <<= '127.0.0.1/24'
184
- User.where(user_arel[:ip_address].contains('127.0.0.1'))
185
- # => SELECT \"users\".* FROM \"users\" WHERE \"users\".\"ip_address\" >> '127.0.0.1'
186
- User.where(user_arel[:ip_address].contains_or_equals('127.0.0.1'))
187
- # => SELECT \"users\".* FROM \"users\" WHERE \"users\".\"ip_address\" >>= '127.0.0.1'
188
- ```
189
-
190
- ## Developing
191
-
192
- To work on postgres\_ext locally, follow these steps:
193
-
194
- 1. Run `bundle install`, this will install (almost) all the development
195
- dependencies
196
- 2. Run `gem install byebug` (not a declared dependency to not break CI)
197
- 3. Run `bundle exec rake db:setup`, this will set up the `.env` file necessary to run
198
- the tests and set up the database
199
- 4. Run `bundle exec rake db:create`, this will create the test database
200
- 5. Run `bundle exec rake db:migrate`, this will set up the database tables required
201
- by the test
202
- 6. Run `BUNDLE_GEMFILE='gemfiles/Gemfile.activerecord-4.0.x' bundle install --quiet` to create the Gemfile.lock for 4.0.
203
- 7. Run `BUNDLE_GEMFILE='gemfiles/Gemfile.activerecord-4.1.x' bundle install --quiet` to create the Gemfile.lock for 4.1.
204
- 8. Run `bundle exec rake test:all` to run tests against all supported versions of Active Record
205
-
206
- ## Authors
207
-
208
- Dan McClain [twitter](http://twitter.com/_danmcclain) [github](http://github.com/danmcclain)
209
-
210
-
211
-
212
-
213
-
214
- Change.arel_table[:diff].has_key?(:in_review)
215
- Change.arel_table[:diff].has_keys?(:in_review, :cached_at)
216
- Change.arel_table[:diff].has_any_key?(:in_review, :nokey)
22
+ arel-extensions extends ActiveRecord's query methods in both Arel and ActiveRecord.
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |gem|
2
2
  gem.name = 'arel-extensions'
3
- gem.version = '1.1.0'
3
+ gem.version = '1.2.0'
4
4
 
5
5
  gem.authors = ["Jon Bracy"]
6
6
  gem.email = ["jonbracy@gmail.com"]
@@ -0,0 +1,37 @@
1
+ require 'active_record'
2
+ require 'active_record/relation'
3
+ require 'active_record/querying'
4
+ require 'active_record/relation/query_methods'
5
+
6
+ module ActiveRecord::QueryMethods
7
+ def distinct_on_values
8
+ @values["distinct_on_values"] || []
9
+ end
10
+
11
+ def distinct_on_values=(value)
12
+ @values["distinct_on_values"] = value
13
+ end
14
+
15
+ def distinct_on(*fields)
16
+ spawn.distinct_on!(*fields)
17
+ end
18
+ alias uniq_on distinct_on
19
+
20
+ def distinct_on!(*fields)
21
+ fields.flatten!
22
+ self.distinct_on_values = fields.map { |x| x.is_a?(Arel::Attributes::Attribute) ? x : klass.arel_table[x] }
23
+ self
24
+ end
25
+ alias uniq_on! distinct_on!
26
+
27
+ def build_arel_with_distinct_on
28
+ arel = build_arel_without_distinct_on
29
+ arel.distinct_on(self.distinct_on_values) if !self.distinct_on_values.empty?
30
+ arel
31
+ end
32
+ alias_method :build_arel_without_distinct_on, :build_arel
33
+ alias_method :build_arel, :build_arel_with_distinct_on
34
+ end
35
+
36
+ ActiveRecord::Querying.delegate :distinct_on, to: :all
37
+ ActiveRecord::Querying.delegate :distinct_on!, to: :all
@@ -1,14 +1,14 @@
1
1
  module Arel
2
2
  module ArrayPredications
3
3
 
4
- def contains(*values)
5
- values = values[0] if values.size == 1 && values[0].is_a?(Array)
6
- Arel::Nodes::Contains.new(self, values)
4
+ # Used by both JSON and ARRAY so it doesn't try to cast to array
5
+ def contains(value)
6
+ Arel::Nodes::Contains.new(self, value)
7
7
  end
8
8
 
9
- def contained_by(*values)
10
- values = values[0] if values.size == 1 && values[0].is_a?(Array)
11
- Arel::Nodes::ContainedBy.new(self, values)
9
+ # Used by both JSON and ARRAY so it doesn't try to cast to array
10
+ def contained_by(value)
11
+ Arel::Nodes::ContainedBy.new(self, value)
12
12
  end
13
13
 
14
14
  def overlaps(*values)
@@ -18,6 +18,8 @@ require File.expand_path('../nodes/ts_match', __FILE__)
18
18
  require File.expand_path('../ts_predications', __FILE__)
19
19
  Arel::Attributes::Attribute.include(Arel::TSPredications)
20
20
 
21
+ require File.expand_path('../../active_record/query_methods', __FILE__)
22
+
21
23
  if defined?(Arel::Visitors::PostgreSQL)
22
24
  require File.expand_path('../visitors/postgresql_extensions', __FILE__)
23
25
  end
@@ -41,7 +41,7 @@ module Arel
41
41
  end
42
42
  else
43
43
  visit(o.relation, collector)
44
- collector << "\#>>'{" << o.name.to_s
44
+ collector << "\#>'{" << o.name.to_s
45
45
  collector << (last_key ? "}'" : ",")
46
46
  end
47
47
  collector
@@ -94,4 +94,4 @@ module Arel
94
94
 
95
95
  end
96
96
  end
97
- end
97
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arel-extensions
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Bracy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-06 00:00:00.000000000 Z
11
+ date: 2017-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: arel
@@ -62,6 +62,7 @@ files:
62
62
  - LICENSE
63
63
  - README.md
64
64
  - arel-extensions.gemspec
65
+ - lib/active_record/query_methods.rb
65
66
  - lib/arel/array_predications.rb
66
67
  - lib/arel/attributes/cast.rb
67
68
  - lib/arel/attributes/key.rb
@@ -98,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
99
  version: '0'
99
100
  requirements: []
100
101
  rubyforge_project:
101
- rubygems_version: 2.6.4
102
+ rubygems_version: 2.6.8
102
103
  signing_key:
103
104
  specification_version: 4
104
105
  summary: Adds support for missing SQL operators and functions to Arel