activerecord_any_of 1.2 → 1.3
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/README.md +5 -38
- data/Rakefile +9 -27
- data/lib/activerecord_any_of/alternative_builder.rb +25 -9
- data/lib/activerecord_any_of/version.rb +1 -1
- data/lib/activerecord_any_of.rb +4 -4
- data/spec/activerecord_any_of_spec.rb +196 -0
- data/spec/db/database.yml +28 -0
- data/spec/db/schema.rb +33 -0
- data/{test → spec}/fixtures/authors.yml +0 -0
- data/{test → spec}/fixtures/posts.yml +0 -0
- data/spec/fixtures/users.yml +9 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/support/models.rb +34 -0
- metadata +76 -203
- data/test/activerecord_any_of_test.rb +0 -114
- data/test/dummy_rails3/README.rdoc +0 -261
- data/test/dummy_rails3/Rakefile +0 -7
- data/test/dummy_rails3/app/assets/javascripts/application.js +0 -15
- data/test/dummy_rails3/app/assets/stylesheets/application.css +0 -13
- data/test/dummy_rails3/app/controllers/application_controller.rb +0 -3
- data/test/dummy_rails3/app/helpers/application_helper.rb +0 -2
- data/test/dummy_rails3/app/models/author.rb +0 -4
- data/test/dummy_rails3/app/models/post.rb +0 -4
- data/test/dummy_rails3/app/models/special_post.rb +0 -2
- data/test/dummy_rails3/app/models/sti_post.rb +0 -2
- data/test/dummy_rails3/app/views/layouts/application.html.erb +0 -14
- data/test/dummy_rails3/config/application.rb +0 -59
- data/test/dummy_rails3/config/boot.rb +0 -10
- data/test/dummy_rails3/config/database.yml +0 -25
- data/test/dummy_rails3/config/environment.rb +0 -5
- data/test/dummy_rails3/config/environments/development.rb +0 -37
- data/test/dummy_rails3/config/environments/production.rb +0 -67
- data/test/dummy_rails3/config/environments/test.rb +0 -37
- data/test/dummy_rails3/config/initializers/backtrace_silencers.rb +0 -7
- data/test/dummy_rails3/config/initializers/inflections.rb +0 -15
- data/test/dummy_rails3/config/initializers/mime_types.rb +0 -5
- data/test/dummy_rails3/config/initializers/secret_token.rb +0 -7
- data/test/dummy_rails3/config/initializers/session_store.rb +0 -8
- data/test/dummy_rails3/config/initializers/wrap_parameters.rb +0 -14
- data/test/dummy_rails3/config/locales/en.yml +0 -5
- data/test/dummy_rails3/config/routes.rb +0 -58
- data/test/dummy_rails3/config.ru +0 -4
- data/test/dummy_rails3/db/development.sqlite3 +0 -0
- data/test/dummy_rails3/db/migrate/20130617172335_create_authors.rb +0 -9
- data/test/dummy_rails3/db/migrate/20130617173313_create_posts.rb +0 -12
- data/test/dummy_rails3/db/schema.rb +0 -31
- data/test/dummy_rails3/db/test.sqlite3 +0 -0
- data/test/dummy_rails3/log/development.log +0 -101
- data/test/dummy_rails3/log/test.log +0 -2875
- data/test/dummy_rails3/public/404.html +0 -26
- data/test/dummy_rails3/public/422.html +0 -26
- data/test/dummy_rails3/public/500.html +0 -25
- data/test/dummy_rails3/public/favicon.ico +0 -0
- data/test/dummy_rails3/script/rails +0 -6
- data/test/dummy_rails3/test/fixtures/authors.yml +0 -7
- data/test/dummy_rails3/test/fixtures/posts.yml +0 -13
- data/test/dummy_rails3/test/unit/author_test.rb +0 -7
- data/test/dummy_rails3/test/unit/post_test.rb +0 -7
- data/test/dummy_rails4/README.rdoc +0 -28
- data/test/dummy_rails4/Rakefile +0 -6
- data/test/dummy_rails4/app/assets/javascripts/application.js +0 -13
- data/test/dummy_rails4/app/assets/stylesheets/application.css +0 -13
- data/test/dummy_rails4/app/controllers/application_controller.rb +0 -5
- data/test/dummy_rails4/app/helpers/application_helper.rb +0 -2
- data/test/dummy_rails4/app/models/author.rb +0 -3
- data/test/dummy_rails4/app/models/post.rb +0 -3
- data/test/dummy_rails4/app/models/special_post.rb +0 -2
- data/test/dummy_rails4/app/models/sti_post.rb +0 -2
- data/test/dummy_rails4/app/views/layouts/application.html.erb +0 -14
- data/test/dummy_rails4/bin/bundle +0 -3
- data/test/dummy_rails4/bin/rails +0 -4
- data/test/dummy_rails4/bin/rake +0 -4
- data/test/dummy_rails4/config/application.rb +0 -23
- data/test/dummy_rails4/config/boot.rb +0 -5
- data/test/dummy_rails4/config/database.yml +0 -25
- data/test/dummy_rails4/config/environment.rb +0 -5
- data/test/dummy_rails4/config/environments/development.rb +0 -29
- data/test/dummy_rails4/config/environments/production.rb +0 -80
- data/test/dummy_rails4/config/environments/test.rb +0 -36
- data/test/dummy_rails4/config/initializers/backtrace_silencers.rb +0 -7
- data/test/dummy_rails4/config/initializers/filter_parameter_logging.rb +0 -4
- data/test/dummy_rails4/config/initializers/inflections.rb +0 -16
- data/test/dummy_rails4/config/initializers/mime_types.rb +0 -5
- data/test/dummy_rails4/config/initializers/secret_token.rb +0 -12
- data/test/dummy_rails4/config/initializers/session_store.rb +0 -3
- data/test/dummy_rails4/config/initializers/wrap_parameters.rb +0 -14
- data/test/dummy_rails4/config/locales/en.yml +0 -23
- data/test/dummy_rails4/config/routes.rb +0 -56
- data/test/dummy_rails4/config.ru +0 -4
- data/test/dummy_rails4/db/development.sqlite3 +0 -0
- data/test/dummy_rails4/db/migrate/20130617172335_create_authors.rb +0 -9
- data/test/dummy_rails4/db/migrate/20130617173313_create_posts.rb +0 -12
- data/test/dummy_rails4/db/schema.rb +0 -31
- data/test/dummy_rails4/db/test.sqlite3 +0 -0
- data/test/dummy_rails4/log/development.log +0 -21
- data/test/dummy_rails4/log/test.log +0 -1527
- data/test/dummy_rails4/public/404.html +0 -58
- data/test/dummy_rails4/public/422.html +0 -58
- data/test/dummy_rails4/public/500.html +0 -57
- data/test/dummy_rails4/public/favicon.ico +0 -0
- data/test/dummy_rails4/test/fixtures/authors.yml +0 -7
- data/test/dummy_rails4/test/fixtures/posts.yml +0 -13
- data/test/dummy_rails4/test/unit/author_test.rb +0 -7
- data/test/dummy_rails4/test/unit/post_test.rb +0 -7
- data/test/test_helper.rb +0 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3086cee8dc2889c8e3f8874ef32631af08c750c2
|
|
4
|
+
data.tar.gz: 5e01aa2499c952e4fc215c24890b215d1749f104
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2288d0dec57e66b4b9b454f6082eca83125d30912044de57aedfc828f8aa20b98137b0d71c7de5b53a81f94a9c2f3ec6b2b6373b7afa1f10be58e1c127013832
|
|
7
|
+
data.tar.gz: 59c3984d1052c8cff9b04cf5bd8bd07b19fef3e3082d7379f56383a6531bf63bf94b002c810c24aa56d899948b14f923313f06a2c41fd78697dbd11632a36c8b
|
data/README.md
CHANGED
|
@@ -17,7 +17,7 @@ expected result, this should have been used :
|
|
|
17
17
|
User.where.any_of({name: 'Doe'}, {active: true})
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
To be true to principle of least surprise, we now automatically expand
|
|
22
22
|
parameters consisting of a single Hash as a hash for each key, so first
|
|
23
23
|
query will indeed generate :
|
|
@@ -156,51 +156,18 @@ OR offline = '1'` ? Or `where email LIKE '%@example.com' AND ( active = '1' OR
|
|
|
156
156
|
offline = '1' )` ? This can quickly get messy and counter intuitive.
|
|
157
157
|
|
|
158
158
|
The MongoId solution is quite elegant. Using `#any_of`, it is made clear which
|
|
159
|
-
conditions are grouped through `OR` and which are grouped through `AND` :
|
|
160
|
-
|
|
161
|
-
* `User.where( "email LIKE '%@example.com" ).any_of({ active: true }, { offline: true })`
|
|
162
|
-
* `fakes = User.where( "email LIKE '%@example.com'" ).where( active: true ); User.any_of( fakes, { offline: true })`
|
|
159
|
+
conditions are grouped through `OR` and which are grouped through `AND` :
|
|
163
160
|
|
|
161
|
+
* `User.where( "email LIKE '%@example.com" ).where.any_of({ active: true }, { offline: true })`
|
|
162
|
+
* `fakes = User.where( "email LIKE '%@example.com'" ).where( active: true ); User.where.any_of( fakes, { offline: true })`
|
|
164
163
|
|
|
165
164
|
## I want this in active_record
|
|
166
165
|
|
|
167
166
|
You can [say it there](https://github.com/rails/rails/pull/10891).
|
|
168
167
|
|
|
169
|
-
|
|
170
168
|
## Running test
|
|
171
169
|
|
|
172
|
-
|
|
173
|
-
have to run them seperately, but it's ok to use the same directory / machine to
|
|
174
|
-
run both.
|
|
175
|
-
|
|
176
|
-
### Running tests with rails-4
|
|
177
|
-
|
|
178
|
-
```shell
|
|
179
|
-
# One time setup
|
|
180
|
-
bundle install --gemfile Gemfile.rails4
|
|
181
|
-
cd test/dummy_rails4
|
|
182
|
-
BUNDLE_GEMFILE=../../Gemfile.rails4 bundle exec rake db:migrate
|
|
183
|
-
BUNDLE_GEMFILE=../../Gemfile.rails4 bundle exec rake db:test:prepare
|
|
184
|
-
cd ../..
|
|
185
|
-
|
|
186
|
-
# Then
|
|
187
|
-
bundle exec rake test
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### Running tests with rails-3
|
|
191
|
-
|
|
192
|
-
```shell
|
|
193
|
-
# One time setup
|
|
194
|
-
bundle install --gemfile Gemfile.rails3
|
|
195
|
-
cd test/dummy_rails3
|
|
196
|
-
BUNDLE_GEMFILE=../../Gemfile.rails3 bundle exec rake db:migrate
|
|
197
|
-
BUNDLE_GEMFILE=../../Gemfile.rails3 bundle exec rake db:test:prepare
|
|
198
|
-
cd ../..
|
|
199
|
-
|
|
200
|
-
# Then
|
|
201
|
-
RAILS_VERSION=3 bundle exec rake test
|
|
202
|
-
```
|
|
203
|
-
|
|
170
|
+
Testing is done using TravisCI. You can use the wonderful [wwtd gem](https://github.com/grosser/wwtd) to run all tests locally. By default, the task to run is `bundle exec rake spec`, and will run against `sqlite3` in memory. You can change the database like so: `DB=postgresql bundle exec rake spec`. Please note that you may need to change the credentials for your database in the `database.yml` file. *Do not commit those changes.*
|
|
204
171
|
|
|
205
172
|
## Pull requests
|
|
206
173
|
|
data/Rakefile
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env rake
|
|
2
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
require 'rubygems'
|
|
5
|
+
require 'bundler/setup'
|
|
6
|
+
require 'activerecord_any_of/version'
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
ENV[ 'BUNDLE_GEMFILE' ] = 'Gemfile.rails3'
|
|
7
|
-
else
|
|
8
|
-
ENV[ 'BUNDLE_GEMFILE' ] = 'Gemfile.rails4'
|
|
9
|
-
end
|
|
8
|
+
task :default => :spec
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
10
|
+
task :spec do
|
|
11
|
+
puts "\n" + (cmd = "bundle exec rspec spec")
|
|
12
|
+
system cmd
|
|
15
13
|
end
|
|
14
|
+
|
|
16
15
|
begin
|
|
17
16
|
require 'rdoc/task'
|
|
18
17
|
rescue LoadError
|
|
@@ -28,20 +27,3 @@ RDoc::Task.new(:rdoc) do |rdoc|
|
|
|
28
27
|
rdoc.rdoc_files.include('README.rdoc')
|
|
29
28
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
30
29
|
end
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
Bundler::GemHelper.install_tasks
|
|
36
|
-
|
|
37
|
-
require 'rake/testtask'
|
|
38
|
-
|
|
39
|
-
Rake::TestTask.new(:test) do |t|
|
|
40
|
-
t.libs << 'lib'
|
|
41
|
-
t.libs << 'test'
|
|
42
|
-
t.pattern = 'test/**/*_test.rb'
|
|
43
|
-
t.verbose = false
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
task :default => :test
|
|
@@ -37,13 +37,23 @@ module ActiverecordAnyOf
|
|
|
37
37
|
self.queries_bind_values += query.bind_values if query.bind_values.any?
|
|
38
38
|
queries_joins_values[:includes].concat(query.includes_values) if query.includes_values.any?
|
|
39
39
|
queries_joins_values[:joins].concat(query.joins_values) if query.joins_values.any?
|
|
40
|
-
queries_joins_values[:references].concat(query.references_values) if
|
|
40
|
+
queries_joins_values[:references].concat(query.references_values) if ActiveRecord::VERSION::MAJOR >= 4 && query.references_values.any?
|
|
41
41
|
query.arel.constraints.reduce(:and)
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def uniq_queries_joins_values
|
|
46
|
-
@uniq_queries_joins_values ||=
|
|
46
|
+
@uniq_queries_joins_values ||= begin
|
|
47
|
+
{ includes: [], joins: [], references: [] }.tap do |values|
|
|
48
|
+
queries_joins_values.each do |join_type, statements|
|
|
49
|
+
if Symbol === statements.first or String === statements.first
|
|
50
|
+
values[ join_type ] = statements.uniq
|
|
51
|
+
else
|
|
52
|
+
values[ join_type ] = statements.uniq( &:to_sql )
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
47
57
|
end
|
|
48
58
|
|
|
49
59
|
def method_missing(method_name, *args, &block)
|
|
@@ -51,7 +61,7 @@ module ActiverecordAnyOf
|
|
|
51
61
|
end
|
|
52
62
|
|
|
53
63
|
def add_joins_to(relation)
|
|
54
|
-
relation = relation.references(uniq_queries_joins_values[:references]) if
|
|
64
|
+
relation = relation.references(uniq_queries_joins_values[:references]) if ActiveRecord::VERSION::MAJOR >= 4
|
|
55
65
|
relation = relation.includes(uniq_queries_joins_values[:includes])
|
|
56
66
|
relation.joins(uniq_queries_joins_values[:joins])
|
|
57
67
|
end
|
|
@@ -60,10 +70,16 @@ module ActiverecordAnyOf
|
|
|
60
70
|
relation.bind_values += queries_bind_values
|
|
61
71
|
relation.includes_values += uniq_queries_joins_values[:includes]
|
|
62
72
|
relation.joins_values += uniq_queries_joins_values[:joins]
|
|
63
|
-
relation.references_values += uniq_queries_joins_values[:references] if
|
|
73
|
+
relation.references_values += uniq_queries_joins_values[:references] if ActiveRecord::VERSION::MAJOR >= 4
|
|
64
74
|
|
|
65
75
|
relation
|
|
66
76
|
end
|
|
77
|
+
|
|
78
|
+
def unprepare_query(query)
|
|
79
|
+
query.gsub(/((?<!\\)'.*?(?<!\\)'|(?<!\\)".*?(?<!\\)")|(\=\ \$\d)/) do |match|
|
|
80
|
+
$2 and $2.gsub(/\=\ \$\d/, "= ?") or match
|
|
81
|
+
end
|
|
82
|
+
end
|
|
67
83
|
end
|
|
68
84
|
|
|
69
85
|
class PositiveBuilder < Builder
|
|
@@ -71,7 +87,7 @@ module ActiverecordAnyOf
|
|
|
71
87
|
|
|
72
88
|
def with_statement_cache
|
|
73
89
|
if queries && queries_bind_values.any?
|
|
74
|
-
relation = where([queries.reduce(:or).to_sql, *queries_bind_values.map { |v| v[1] }])
|
|
90
|
+
relation = where([unprepare_query(queries.reduce(:or).to_sql), *queries_bind_values.map { |v| v[1] }])
|
|
75
91
|
else
|
|
76
92
|
relation = where(queries.reduce(:or).to_sql)
|
|
77
93
|
end
|
|
@@ -89,15 +105,15 @@ module ActiverecordAnyOf
|
|
|
89
105
|
private
|
|
90
106
|
|
|
91
107
|
def with_statement_cache
|
|
92
|
-
if
|
|
108
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
93
109
|
if queries && queries_bind_values.any?
|
|
94
|
-
relation = where.not([queries.reduce(:or).to_sql, *queries_bind_values.map { |v| v[1] }])
|
|
110
|
+
relation = where.not([unprepare_query(queries.reduce(:or).to_sql), *queries_bind_values.map { |v| v[1] }])
|
|
95
111
|
else
|
|
96
112
|
relation = where.not(queries.reduce(:or).to_sql)
|
|
97
113
|
end
|
|
98
114
|
else
|
|
99
115
|
if queries && queries_bind_values.any?
|
|
100
|
-
relation = where([Arel::Nodes::Not.new(queries.reduce(:or)).to_sql, *queries_bind_values.map { |v| v[1] }])
|
|
116
|
+
relation = where([unprepare_query(Arel::Nodes::Not.new(queries.reduce(:or)).to_sql), *queries_bind_values.map { |v| v[1] }])
|
|
101
117
|
else
|
|
102
118
|
relation = where(Arel::Nodes::Not.new(queries.reduce(:or)).to_sql)
|
|
103
119
|
end
|
|
@@ -107,7 +123,7 @@ module ActiverecordAnyOf
|
|
|
107
123
|
end
|
|
108
124
|
|
|
109
125
|
def without_statement_cache
|
|
110
|
-
if
|
|
126
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
111
127
|
relation = where.not(queries.reduce(:or))
|
|
112
128
|
else
|
|
113
129
|
relation = where(Arel::Nodes::Not.new(queries.reduce(:or)))
|
data/lib/activerecord_any_of.rb
CHANGED
|
@@ -57,7 +57,7 @@ module ActiverecordAnyOf
|
|
|
57
57
|
|
|
58
58
|
module Deprecated
|
|
59
59
|
def any_of(*queries)
|
|
60
|
-
if
|
|
60
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
61
61
|
ActiveSupport::Deprecation.warn( "Calling #any_of directly is deprecated and will be removed in activerecord_any_of-1.2.\nPlease call it with #where : User.where.any_of(cond1, cond2)." )
|
|
62
62
|
end
|
|
63
63
|
|
|
@@ -66,7 +66,7 @@ module ActiverecordAnyOf
|
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
def none_of(*queries)
|
|
69
|
-
if
|
|
69
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
70
70
|
ActiveSupport::Deprecation.warn( "Calling #none_of directly is deprecated and will be removed in activerecord_any_of-1.2.\nPlease call it with #where : User.where.none_of(cond1, cond2)." )
|
|
71
71
|
end
|
|
72
72
|
|
|
@@ -76,7 +76,7 @@ module ActiverecordAnyOf
|
|
|
76
76
|
end
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
-
if
|
|
79
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
80
80
|
module ActiverecordAnyOfDelegation
|
|
81
81
|
delegate :any_of, to: :all
|
|
82
82
|
delegate :none_of, to: :all
|
|
@@ -89,5 +89,5 @@ else
|
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
ActiveRecord::Relation.send(:include, ActiverecordAnyOf::Deprecated)
|
|
92
|
-
ActiveRecord::Relation::WhereChain.send(:include, ActiverecordAnyOf::Chained) if
|
|
92
|
+
ActiveRecord::Relation::WhereChain.send(:include, ActiverecordAnyOf::Chained) if ActiveRecord::VERSION::MAJOR >= 4
|
|
93
93
|
ActiveRecord::Base.send(:extend, ActiverecordAnyOfDelegation)
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ActiverecordAnyOf do
|
|
4
|
+
fixtures :authors, :posts, :users
|
|
5
|
+
|
|
6
|
+
describe 'finding with alternate conditions' do
|
|
7
|
+
let(:davids) { Author.where(name: "David") }
|
|
8
|
+
|
|
9
|
+
it "matches hash combinations" do
|
|
10
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
11
|
+
expect(Author.where.any_of({name: 'David'}, {name: 'Mary'})).to match_array(authors(:david, :mary))
|
|
12
|
+
else
|
|
13
|
+
expect(Author.any_of({name: 'David'}, {name: 'Mary'})).to match_array(authors(:david, :mary))
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "matches combination of hash and array" do
|
|
18
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
19
|
+
expect(Author.where.any_of({name: 'David'}, ['name = ?', 'Mary'])).to match_array(authors(:david, :mary))
|
|
20
|
+
else
|
|
21
|
+
expect(Author.any_of({name: 'David'}, ['name = ?', 'Mary'])).to match_array(authors(:david, :mary))
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "matches a combination of hashes, arrays, and AR relations" do
|
|
26
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
27
|
+
expect(Author.where.any_of(davids, ['name = ?', 'Mary'], {name: 'Bob'})).to match_array(authors(:david, :mary, :bob))
|
|
28
|
+
else
|
|
29
|
+
expect(Author.any_of(davids, ['name = ?', 'Mary'], {name: 'Bob'})).to match_array(authors(:david, :mary, :bob))
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "matches a combination of strings, hashes, and AR relations" do
|
|
34
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
35
|
+
expect(Author.where.any_of(davids, "name = 'Mary'", {name: 'Bob', id: 3})).to match_array(authors(:david, :mary, :bob))
|
|
36
|
+
else
|
|
37
|
+
expect(Author.any_of(davids, "name = 'Mary'", {name: 'Bob', id: 3})).to match_array(authors(:david, :mary, :bob))
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "doesn't find combinations previously filtered out" do
|
|
42
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
43
|
+
expect(Author.where.not(name: 'Mary').where.any_of(davids, ['name = ?', 'Mary'])).to match_array([authors(:david)])
|
|
44
|
+
else
|
|
45
|
+
expect(Author.where("name != 'Mary'").any_of(davids, ['name = ?', 'Mary'])).to match_array([authors(:david)])
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'finding with alternate conditions on has_many association' do
|
|
51
|
+
david = authors(:david)
|
|
52
|
+
welcome = david.posts.where(body: 'Such a lovely day')
|
|
53
|
+
expected = ['Welcome to the weblog', 'So I was thinking']
|
|
54
|
+
|
|
55
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
56
|
+
expect(david.posts.where.any_of(welcome, {type: 'SpecialPost'}).map(&:title)).to match_array(expected)
|
|
57
|
+
else
|
|
58
|
+
expect(david.posts.any_of(welcome, {type: 'SpecialPost'}).map(&:title)).to match_array(expected)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'finds with combined polymorphic associations' do
|
|
63
|
+
company = Company.create!
|
|
64
|
+
university = University.create!
|
|
65
|
+
|
|
66
|
+
company.users << users(:ezra)
|
|
67
|
+
university.users << users(:aria)
|
|
68
|
+
|
|
69
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
70
|
+
expect(User.where.any_of(company.users, university.users)).to match_array(users(:ezra, :aria))
|
|
71
|
+
else
|
|
72
|
+
expect(User.any_of(company.users, university.users)).to match_array(users(:ezra, :aria))
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it 'finds with more than 2 combined polymorphic associations' do
|
|
77
|
+
company = Company.create!
|
|
78
|
+
university = University.create!
|
|
79
|
+
company2 = Company.create!
|
|
80
|
+
|
|
81
|
+
company.users << users(:ezra)
|
|
82
|
+
university.users << users(:aria)
|
|
83
|
+
company2.users << users(:james)
|
|
84
|
+
|
|
85
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
86
|
+
expect(User.where.any_of(company.users, university.users, company2.users)).to match_array(users(:ezra, :aria, :james))
|
|
87
|
+
else
|
|
88
|
+
expect(User.any_of(company.users, university.users, company2.users)).to match_array(users(:ezra, :aria, :james))
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it 'finds alternatives with combined has_many associations' do
|
|
93
|
+
david, mary = authors(:david, :mary)
|
|
94
|
+
|
|
95
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
96
|
+
expect(Post.where.any_of(david.posts, mary.posts)).to match_array(david.posts + mary.posts)
|
|
97
|
+
else
|
|
98
|
+
expect(Post.any_of(david.posts, mary.posts)).to match_array(david.posts + mary.posts)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it 'finds alternatives with more than 2 combined has_many associations' do
|
|
103
|
+
david, mary, bob = authors(:david, :mary, :bob)
|
|
104
|
+
|
|
105
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
106
|
+
expect(Post.where.any_of(david.posts, mary.posts, bob.posts)).to match_array(david.posts + mary.posts + bob.posts)
|
|
107
|
+
else
|
|
108
|
+
expect(Post.any_of(david.posts, mary.posts, bob.posts)).to match_array(david.posts + mary.posts + bob.posts)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
describe 'finding alternate dynamically with joined queries' do
|
|
113
|
+
it "matches combined AR relations with joins" do
|
|
114
|
+
david = Author.where(posts: { title: 'Welcome to the weblog' }).joins(:posts)
|
|
115
|
+
mary = Author.where(posts: { title: "eager loading with OR'd conditions" }).joins(:posts)
|
|
116
|
+
|
|
117
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
118
|
+
expect(Author.where.any_of(david, mary)).to match_array(authors(:david, :mary))
|
|
119
|
+
else
|
|
120
|
+
expect(Author.any_of(david, mary)).to match_array(authors(:david, :mary))
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "matches combined AR relations with joins and includes" do
|
|
125
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
126
|
+
david = Author.where(posts: { title: 'Welcome to the weblog' }).includes(:posts).references(:posts)
|
|
127
|
+
mary = Author.where(posts: { title: "eager loading with OR'd conditions" }).includes(:posts).references(:posts)
|
|
128
|
+
expect(Author.where.any_of(david, mary)).to match_array(authors(:david, :mary))
|
|
129
|
+
else
|
|
130
|
+
david = Author.where(posts: { title: 'Welcome to the weblog' }).includes(:posts)
|
|
131
|
+
mary = Author.where(posts: { title: "eager loading with OR'd conditions" }).includes(:posts)
|
|
132
|
+
expect(Author.any_of(david, mary)).to match_array(authors(:david, :mary))
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it 'finding with alternate negative conditions' do
|
|
138
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
139
|
+
expect(Author.where.none_of({name: 'David'}, {name: 'Mary'})).to match_array([authors(:bob)])
|
|
140
|
+
else
|
|
141
|
+
expect(Author.none_of({name: 'David'}, {name: 'Mary'})).to match_array([authors(:bob)])
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it 'finding with alternate negative conditions on association' do
|
|
146
|
+
david = Author.where(name: 'David').first
|
|
147
|
+
welcome = david.posts.where(body: 'Such a lovely day')
|
|
148
|
+
expected = ['sti comments', 'sti me', 'habtm sti test']
|
|
149
|
+
|
|
150
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
151
|
+
expect(david.posts.where.none_of(welcome, {type: 'SpecialPost'}).map(&:title)).to match_array(expected)
|
|
152
|
+
else
|
|
153
|
+
expect(david.posts.none_of(welcome, {type: 'SpecialPost'}).map(&:title)).to match_array(expected)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it 'calling #any_of with no argument raise exception' do
|
|
158
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
159
|
+
expect { Author.where.any_of }.to raise_exception(ArgumentError)
|
|
160
|
+
else
|
|
161
|
+
expect { Author.any_of }.to raise_exception(ArgumentError)
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it 'calling #none_of with no argument raise exception' do
|
|
166
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
167
|
+
expect { Author.where.none_of }.to raise_exception(ArgumentError)
|
|
168
|
+
else
|
|
169
|
+
expect { Author.none_of }.to raise_exception(ArgumentError)
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
it 'calling #any_of after a wildcard query works' do
|
|
174
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
175
|
+
expect(Author.where("name like '%av%'").where.any_of({name: 'David'}, {name: 'Mary'})).to match_array([authors(:david)])
|
|
176
|
+
else
|
|
177
|
+
expect(Author.where("name like '%av%'").any_of({name: 'David'}, {name: 'Mary'})).to match_array([authors(:david)])
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
it 'calling #any_of with a single Hash as parameter expands it' do
|
|
182
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
183
|
+
expect(Author.where.any_of(name: 'David', id: 2)).to match_array(authors(:david, :mary))
|
|
184
|
+
else
|
|
185
|
+
expect(Author.any_of(name: 'David', id: 2)).to match_array(authors(:david, :mary))
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
|
190
|
+
it 'calling directly #any_of is deprecated in rails-4' do
|
|
191
|
+
allow(ActiveSupport::Deprecation).to receive(:warn)
|
|
192
|
+
Author.any_of({name: 'David'}, {name: 'Mary'})
|
|
193
|
+
expect(ActiveSupport::Deprecation).to have_received(:warn)
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
sqlite3:
|
|
2
|
+
adapter: <%= "jdbc" if defined? JRUBY_VERSION %>sqlite3
|
|
3
|
+
database: activerecord_any_of.sqlite3.db
|
|
4
|
+
sqlite3mem:
|
|
5
|
+
adapter: <%= "jdbc" if defined? JRUBY_VERSION %>sqlite3
|
|
6
|
+
database: ":memory:"
|
|
7
|
+
postgresql:
|
|
8
|
+
adapter: postgresql
|
|
9
|
+
encoding: unicode
|
|
10
|
+
database: activerecord_any_of_test
|
|
11
|
+
pool: 5
|
|
12
|
+
username: postgres
|
|
13
|
+
password:
|
|
14
|
+
min_messages: warning
|
|
15
|
+
mysql:
|
|
16
|
+
adapter: <%= defined?(JRUBY_VERSION) ? "jdbcmysql" : "mysql2" %>
|
|
17
|
+
host: localhost
|
|
18
|
+
username: root
|
|
19
|
+
password:
|
|
20
|
+
database: activerecord_any_of_test
|
|
21
|
+
encoding: utf8
|
|
22
|
+
## Add DB Configuration to run Oracle tests
|
|
23
|
+
oracle:
|
|
24
|
+
adapter: oracle_enhanced
|
|
25
|
+
host: localhost
|
|
26
|
+
username: activerecord_any_of_dev
|
|
27
|
+
password:
|
|
28
|
+
database: xe
|
data/spec/db/schema.rb
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
ActiveRecord::Schema.define do
|
|
2
|
+
create_table :authors do |t|
|
|
3
|
+
t.string :name
|
|
4
|
+
t.datetime :created_at
|
|
5
|
+
t.datetime :updated_at
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
create_table :posts do |t|
|
|
9
|
+
t.string :title
|
|
10
|
+
t.text :body
|
|
11
|
+
t.integer :author_id
|
|
12
|
+
t.string :type
|
|
13
|
+
t.datetime :created_at
|
|
14
|
+
t.datetime :updated_at
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
create_table :companies do |t|
|
|
18
|
+
t.string :name
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
create_table :universities do |t|
|
|
22
|
+
t.string :name
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
create_table :memberships do |t|
|
|
26
|
+
t.references :organization, polymorphic: true
|
|
27
|
+
t.references :user
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
create_table :users do |t|
|
|
31
|
+
t.string :name
|
|
32
|
+
end
|
|
33
|
+
end
|
|
File without changes
|
|
File without changes
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
plugin_test_dir = File.dirname(__FILE__)
|
|
2
|
+
|
|
3
|
+
require 'rubygems'
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
require 'pry'
|
|
6
|
+
|
|
7
|
+
require 'logger'
|
|
8
|
+
require 'rails/all'
|
|
9
|
+
require 'active_record'
|
|
10
|
+
ActiveRecord::Base.logger = Logger.new(plugin_test_dir + "/debug.log")
|
|
11
|
+
|
|
12
|
+
require 'yaml'
|
|
13
|
+
require 'erb'
|
|
14
|
+
ActiveRecord::Base.configurations = YAML::load(ERB.new(IO.read(plugin_test_dir + "/db/database.yml")).result)
|
|
15
|
+
ActiveRecord::Base.establish_connection((ENV["DB"] ||= 'sqlite3mem').to_sym)
|
|
16
|
+
ActiveRecord::Migration.verbose = false
|
|
17
|
+
|
|
18
|
+
require 'combustion/database'
|
|
19
|
+
Combustion::Database.create_database(ActiveRecord::Base.configurations[ENV["DB"]])
|
|
20
|
+
load(File.join(plugin_test_dir, "db", "schema.rb"))
|
|
21
|
+
|
|
22
|
+
require 'activerecord_any_of'
|
|
23
|
+
require 'support/models'
|
|
24
|
+
|
|
25
|
+
require 'action_controller'
|
|
26
|
+
require 'rspec/rails'
|
|
27
|
+
require 'database_cleaner'
|
|
28
|
+
RSpec.configure do |config|
|
|
29
|
+
config.fixture_path = "#{plugin_test_dir}/fixtures"
|
|
30
|
+
config.use_transactional_fixtures = true
|
|
31
|
+
config.after(:suite) do
|
|
32
|
+
unless /sqlite/ === ENV['DB']
|
|
33
|
+
Combustion::Database.drop_database(ActiveRecord::Base.configurations[ENV['DB']])
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
class Author < ActiveRecord::Base
|
|
2
|
+
has_many :posts
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
class Post < ActiveRecord::Base
|
|
6
|
+
belongs_to :author
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class SpecialPost < Post
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class StiPost < Post
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class User < ActiveRecord::Base
|
|
16
|
+
has_many :memberships
|
|
17
|
+
has_many :companies, through: :memberships, source: :organization, source_type: "Company"
|
|
18
|
+
has_many :universities, through: :memberships, source: :organization, source_type: "University"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class Membership < ActiveRecord::Base
|
|
22
|
+
belongs_to :user
|
|
23
|
+
belongs_to :organization, polymorphic: true
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class Company < ActiveRecord::Base
|
|
27
|
+
has_many :memberships, as: :organization
|
|
28
|
+
has_many :users, through: :memberships
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class University < ActiveRecord::Base
|
|
32
|
+
has_many :memberships, as: :organization
|
|
33
|
+
has_many :users, through: :memberships
|
|
34
|
+
end
|