active_hash_relation 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +2 -0
- data/.travis.yml +15 -0
- data/README.md +68 -11
- data/active_hash_relation.gemspec +13 -0
- data/lib/active_hash_relation.rb +18 -12
- data/lib/active_hash_relation/aggregation.rb +3 -0
- data/lib/active_hash_relation/association_filters.rb +3 -0
- data/lib/active_hash_relation/column_filters.rb +45 -11
- data/lib/active_hash_relation/filter_applier.rb +37 -23
- data/lib/active_hash_relation/helpers.rb +22 -2
- data/lib/active_hash_relation/scope_filters.rb +8 -1
- data/lib/active_hash_relation/sort_filters.rb +12 -0
- data/lib/active_hash_relation/version.rb +1 -1
- data/lib/active_record/scope_names.rb +4 -19
- data/lib/generators/active_hash_relation/initialize_generator.rb +13 -0
- data/lib/generators/active_hash_relation/templates/active_hash_relation.rb +12 -0
- data/spec/config/initializers/active_hash_relation.rb +16 -0
- data/spec/db/migrate/001_basic_schema.rb +53 -0
- data/spec/dummy-rails4/.gitignore +13 -0
- data/spec/dummy-rails4/.ruby-version +1 -0
- data/spec/dummy-rails4/Gemfile +18 -0
- data/spec/dummy-rails4/README.md +3 -0
- data/spec/dummy-rails4/Rakefile +6 -0
- data/spec/dummy-rails4/app/controllers/application_controller.rb +5 -0
- data/spec/dummy-rails4/app/models/.keep +0 -0
- data/spec/dummy-rails4/app/models/address.rb +1 -0
- data/spec/dummy-rails4/app/models/micropost.rb +1 -0
- data/spec/dummy-rails4/app/models/relationship.rb +1 -0
- data/spec/dummy-rails4/app/models/user.rb +1 -0
- data/spec/dummy-rails4/bin/bundle +3 -0
- data/spec/dummy-rails4/bin/rails +4 -0
- data/spec/dummy-rails4/bin/rake +4 -0
- data/spec/dummy-rails4/bin/setup +29 -0
- data/spec/dummy-rails4/config.ru +4 -0
- data/spec/dummy-rails4/config/application.rb +35 -0
- data/spec/dummy-rails4/config/boot.rb +3 -0
- data/spec/dummy-rails4/config/database.yml +18 -0
- data/spec/dummy-rails4/config/environment.rb +5 -0
- data/spec/dummy-rails4/config/environments/development.rb +41 -0
- data/spec/dummy-rails4/config/environments/production.rb +79 -0
- data/spec/dummy-rails4/config/environments/test.rb +42 -0
- data/spec/dummy-rails4/config/initializers/active_hash_relation.rb +3 -0
- data/spec/dummy-rails4/config/initializers/assets.rb +11 -0
- data/spec/dummy-rails4/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy-rails4/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy-rails4/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy-rails4/config/initializers/inflections.rb +16 -0
- data/spec/dummy-rails4/config/initializers/mime_types.rb +4 -0
- data/spec/dummy-rails4/config/initializers/session_store.rb +3 -0
- data/spec/dummy-rails4/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy-rails4/config/locales/en.yml +23 -0
- data/spec/dummy-rails4/config/routes.rb +56 -0
- data/spec/dummy-rails4/config/secrets.yml +22 -0
- data/spec/dummy-rails4/db/migrate/001_basic_schema.rb +1 -0
- data/spec/dummy-rails4/db/schema.rb +69 -0
- data/spec/dummy-rails4/spec/factories/factories.rb +1 -0
- data/spec/dummy-rails4/spec/rails_helper.rb +19 -0
- data/spec/dummy-rails4/spec/spec_helper.rb +99 -0
- data/spec/dummy-rails4/spec/support/support.rb +1 -0
- data/spec/dummy-rails4/spec/tests/tests_spec.rb +3 -0
- data/spec/dummy-rails5/.gitignore +17 -0
- data/spec/dummy-rails5/.rspec +2 -0
- data/spec/dummy-rails5/.ruby-version +1 -0
- data/spec/dummy-rails5/Gemfile +19 -0
- data/spec/dummy-rails5/README.md +3 -0
- data/spec/dummy-rails5/Rakefile +6 -0
- data/spec/dummy-rails5/app/controllers/application_controller.rb +3 -0
- data/spec/dummy-rails5/app/models/address.rb +1 -0
- data/spec/dummy-rails5/app/models/micropost.rb +1 -0
- data/spec/dummy-rails5/app/models/relationship.rb +1 -0
- data/spec/dummy-rails5/app/models/user.rb +1 -0
- data/spec/dummy-rails5/bin/bundle +3 -0
- data/spec/dummy-rails5/bin/rails +4 -0
- data/spec/dummy-rails5/bin/rake +4 -0
- data/spec/dummy-rails5/bin/setup +34 -0
- data/spec/dummy-rails5/bin/update +29 -0
- data/spec/dummy-rails5/config.ru +5 -0
- data/spec/dummy-rails5/config/application.rb +25 -0
- data/spec/dummy-rails5/config/boot.rb +3 -0
- data/spec/dummy-rails5/config/cable.yml +9 -0
- data/spec/dummy-rails5/config/database.yml +18 -0
- data/spec/dummy-rails5/config/environment.rb +5 -0
- data/spec/dummy-rails5/config/environments/development.rb +54 -0
- data/spec/dummy-rails5/config/environments/production.rb +86 -0
- data/spec/dummy-rails5/config/environments/test.rb +42 -0
- data/spec/dummy-rails5/config/initializers/active_hash_relation.rb +3 -0
- data/spec/dummy-rails5/config/initializers/application_controller_renderer.rb +6 -0
- data/spec/dummy-rails5/config/initializers/assets.rb +11 -0
- data/spec/dummy-rails5/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy-rails5/config/initializers/cookies_serializer.rb +5 -0
- data/spec/dummy-rails5/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy-rails5/config/initializers/inflections.rb +16 -0
- data/spec/dummy-rails5/config/initializers/mime_types.rb +4 -0
- data/spec/dummy-rails5/config/initializers/new_framework_defaults.rb +24 -0
- data/spec/dummy-rails5/config/initializers/session_store.rb +3 -0
- data/spec/dummy-rails5/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy-rails5/config/locales/en.yml +23 -0
- data/spec/dummy-rails5/config/puma.rb +47 -0
- data/spec/dummy-rails5/config/routes.rb +3 -0
- data/spec/dummy-rails5/config/secrets.yml +22 -0
- data/spec/dummy-rails5/config/spring.rb +6 -0
- data/spec/dummy-rails5/db/migrate/001_basic_schema.rb +2 -0
- data/spec/dummy-rails5/db/schema.rb +64 -0
- data/spec/dummy-rails5/spec/factories/factories.rb +1 -0
- data/spec/dummy-rails5/spec/rails_helper.rb +19 -0
- data/spec/dummy-rails5/spec/spec_helper.rb +99 -0
- data/spec/dummy-rails5/spec/support/support.rb +1 -0
- data/spec/dummy-rails5/spec/tests/tests_spec.rb +3 -0
- data/spec/factories/factories.rb +39 -0
- data/spec/models/address.rb +7 -0
- data/spec/models/application_record.rb +3 -0
- data/spec/models/micropost.rb +9 -0
- data/spec/models/relationship.rb +9 -0
- data/spec/models/user.rb +32 -0
- data/spec/support/support.rb +62 -0
- data/spec/tests/aggregations/avg_spec.rb +45 -0
- data/spec/tests/aggregations/max_spec.rb +45 -0
- data/spec/tests/aggregations/min_spec.rb +46 -0
- data/spec/tests/aggregations/sum_spec.rb +43 -0
- data/spec/tests/associations/belongs_to_spec.rb +96 -0
- data/spec/tests/associations/has_many_spec.rb +91 -0
- data/spec/tests/associations/has_one_spec.rb +89 -0
- data/spec/tests/booleans_spec.rb +29 -0
- data/spec/tests/limit_spec.rb +30 -0
- data/spec/tests/null_spec.rb +44 -0
- data/spec/tests/numbers_spec.rb +142 -0
- data/spec/tests/or_filter_spec.rb +98 -0
- data/spec/tests/primary_key_spec.rb +29 -0
- data/spec/tests/scopes_spec.rb +48 -0
- data/spec/tests/sorting_spec.rb +100 -0
- data/spec/tests/strings_spec.rb +86 -0
- metadata +392 -4
@@ -0,0 +1,9 @@
|
|
1
|
+
require_relative './application_record'
|
2
|
+
|
3
|
+
class Micropost < ApplicationRecord
|
4
|
+
belongs_to :user, counter_cache: true
|
5
|
+
|
6
|
+
enum status: {draft: 0, published: 1, archived: 2 }
|
7
|
+
|
8
|
+
scope :created_on, ->(date) {where("date(microposts.created_at) = ?", date.to_date)}
|
9
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require_relative './application_record'
|
2
|
+
|
3
|
+
class Relationship < ApplicationRecord
|
4
|
+
belongs_to :follower, class_name: "User", counter_cache: :followings_count
|
5
|
+
belongs_to :followed, class_name: "User", counter_cache: :followers_count
|
6
|
+
|
7
|
+
validates :follower_id, presence: true
|
8
|
+
validates :followed_id, presence: true
|
9
|
+
end
|
data/spec/models/user.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative './application_record'
|
2
|
+
|
3
|
+
class User < ApplicationRecord
|
4
|
+
has_many :microposts, dependent: :destroy
|
5
|
+
has_many :active_relationships, class_name: "Relationship",
|
6
|
+
foreign_key: "follower_id",
|
7
|
+
dependent: :destroy
|
8
|
+
has_many :passive_relationships, class_name: "Relationship",
|
9
|
+
foreign_key: "followed_id",
|
10
|
+
dependent: :destroy
|
11
|
+
has_many :following, through: :active_relationships, source: :followed
|
12
|
+
has_many :followers, through: :passive_relationships, source: :follower
|
13
|
+
has_one :address
|
14
|
+
|
15
|
+
before_validation :ensure_token
|
16
|
+
|
17
|
+
scope :unverified, -> {where(verified: false)}
|
18
|
+
scope :unsocial, -> {where(followings_count: 0, followers_count: 0)}
|
19
|
+
scope :created_on, ->(date) {where("date(created_at) = ?", date.to_date)}
|
20
|
+
|
21
|
+
private
|
22
|
+
def ensure_token
|
23
|
+
self.token = generate_hex(:token) unless token.present?
|
24
|
+
end
|
25
|
+
|
26
|
+
def generate_hex(column)
|
27
|
+
loop do
|
28
|
+
hex = SecureRandom.hex
|
29
|
+
break hex unless self.class.where(column => hex).any?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
RSpec.configure do |config|
|
2
|
+
config.before :suite do
|
3
|
+
DatabaseCleaner[:active_record].strategy = :transaction
|
4
|
+
DatabaseCleaner.clean_with(:truncation)
|
5
|
+
end
|
6
|
+
|
7
|
+
config.around(:each) do |example|
|
8
|
+
DatabaseCleaner.cleaning do
|
9
|
+
example.run
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
RSpec.configure do |config|
|
15
|
+
config.include FactoryGirl::Syntax::Methods
|
16
|
+
|
17
|
+
config.before(:suite) do
|
18
|
+
begin
|
19
|
+
DatabaseCleaner.start
|
20
|
+
FactoryGirl.lint
|
21
|
+
ensure
|
22
|
+
DatabaseCleaner.clean
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class HelperClass
|
28
|
+
include ActiveHashRelation
|
29
|
+
end
|
30
|
+
|
31
|
+
module Helpers
|
32
|
+
def strip(query)
|
33
|
+
query.gsub("\"","").gsub(/\s+/, ' ')
|
34
|
+
end
|
35
|
+
|
36
|
+
def select_all(table)
|
37
|
+
ExpectedQuery.new("SELECT #{table}.* FROM users WHERE")
|
38
|
+
end
|
39
|
+
alias_method :select_all_where, :select_all
|
40
|
+
|
41
|
+
def query(str)
|
42
|
+
ExpectedQuery.new(str, subquery: true)
|
43
|
+
end
|
44
|
+
|
45
|
+
def q(*args)
|
46
|
+
args.each.with_index.inject(''){|memo, (str, index)|
|
47
|
+
if args[index-1] == '('
|
48
|
+
"#{memo}#{str}"
|
49
|
+
elsif str == ')'
|
50
|
+
"#{memo}#{str}"
|
51
|
+
else
|
52
|
+
"#{memo} #{str}"
|
53
|
+
end
|
54
|
+
}.strip
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class Array
|
59
|
+
def avg
|
60
|
+
sum / size.to_f
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
describe ActiveHashRelation do
|
2
|
+
include Helpers
|
3
|
+
|
4
|
+
context 'aggregations' do
|
5
|
+
context 'avg' do
|
6
|
+
before do
|
7
|
+
FactoryGirl.create_list(:micropost, 10)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "one aggregation" do
|
11
|
+
hash = { aggregate: {likes: {avg: true} } }
|
12
|
+
|
13
|
+
aggregations = HelperClass.new.aggregations(Micropost.all, hash)
|
14
|
+
expected_aggregations = HashWithIndifferentAccess.new({
|
15
|
+
likes: {
|
16
|
+
avg: Micropost.pluck(:likes).avg
|
17
|
+
}
|
18
|
+
})
|
19
|
+
expect(aggregations).to eq expected_aggregations
|
20
|
+
end
|
21
|
+
it "multiple aggregations" do
|
22
|
+
hash = {
|
23
|
+
aggregate: {
|
24
|
+
likes: {avg: true}, reposts: {avg: true}, created_at: {avg: true}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
aggregations = HelperClass.new.aggregations(Micropost.all, hash)
|
29
|
+
expected_aggregations = HashWithIndifferentAccess.new({
|
30
|
+
likes: {
|
31
|
+
avg: Micropost.pluck(:likes).avg
|
32
|
+
},
|
33
|
+
reposts: {
|
34
|
+
avg: Micropost.pluck(:reposts).avg
|
35
|
+
},
|
36
|
+
created_at: {}
|
37
|
+
})
|
38
|
+
expect(aggregations).to eq expected_aggregations
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
describe ActiveHashRelation do
|
2
|
+
include Helpers
|
3
|
+
|
4
|
+
context 'aggregations' do
|
5
|
+
context 'max' do
|
6
|
+
before do
|
7
|
+
FactoryGirl.create_list(:micropost, 10)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "one aggregation" do
|
11
|
+
hash = { aggregate: {likes: {max: true} } }
|
12
|
+
|
13
|
+
aggregations = HelperClass.new.aggregations(Micropost.all, hash)
|
14
|
+
expected_aggregations = HashWithIndifferentAccess.new({
|
15
|
+
likes: {
|
16
|
+
max: Micropost.pluck(:likes).max
|
17
|
+
}
|
18
|
+
})
|
19
|
+
expect(aggregations).to eq expected_aggregations
|
20
|
+
end
|
21
|
+
it "multiple aggregations" do
|
22
|
+
hash = {
|
23
|
+
aggregate: {
|
24
|
+
likes: {max: true}, reposts: {max: true}, created_at: {max: true}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
aggregations = HelperClass.new.aggregations(Micropost.all, hash)
|
29
|
+
expected_aggregations = HashWithIndifferentAccess.new({
|
30
|
+
likes: {
|
31
|
+
max: Micropost.pluck(:likes).max,
|
32
|
+
},
|
33
|
+
reposts: {
|
34
|
+
max: Micropost.pluck(:reposts).max,
|
35
|
+
},
|
36
|
+
created_at: {
|
37
|
+
max: Micropost.pluck(:created_at).max.to_time
|
38
|
+
}
|
39
|
+
})
|
40
|
+
expect(aggregations).to eq expected_aggregations
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
describe ActiveHashRelation do
|
2
|
+
include Helpers
|
3
|
+
|
4
|
+
context 'aggregations' do
|
5
|
+
context 'min' do
|
6
|
+
before do
|
7
|
+
FactoryGirl.create_list(:micropost, 10)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "one aggregation" do
|
11
|
+
hash = { aggregate: {likes: {min: true} } }
|
12
|
+
|
13
|
+
aggregations = HelperClass.new.aggregations(Micropost.all, hash)
|
14
|
+
expected_aggregations = HashWithIndifferentAccess.new({
|
15
|
+
likes: {
|
16
|
+
min: Micropost.pluck(:likes).min
|
17
|
+
}
|
18
|
+
})
|
19
|
+
expect(aggregations).to eq expected_aggregations
|
20
|
+
end
|
21
|
+
it "multiple aggregations" do
|
22
|
+
hash = {
|
23
|
+
aggregate: {
|
24
|
+
likes: {min: true}, reposts: {min: true}, created_at: {min: true}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
aggregations = HelperClass.new.aggregations(Micropost.all, hash)
|
29
|
+
expected_aggregations = HashWithIndifferentAccess.new({
|
30
|
+
likes: {
|
31
|
+
min: Micropost.pluck(:likes).min
|
32
|
+
},
|
33
|
+
reposts: {
|
34
|
+
min: Micropost.pluck(:reposts).min
|
35
|
+
},
|
36
|
+
created_at: {
|
37
|
+
min: Micropost.pluck(:created_at).min.to_time
|
38
|
+
}
|
39
|
+
})
|
40
|
+
expect(aggregations).to eq expected_aggregations
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
describe ActiveHashRelation do
|
2
|
+
include Helpers
|
3
|
+
|
4
|
+
context 'aggregations' do
|
5
|
+
context 'sum' do
|
6
|
+
before do
|
7
|
+
FactoryGirl.create_list(:micropost, 10)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "one aggregation" do
|
11
|
+
hash = { aggregate: {likes: {sum: true} } }
|
12
|
+
|
13
|
+
aggregations = HelperClass.new.aggregations(Micropost.all, hash)
|
14
|
+
expected_aggregations = HashWithIndifferentAccess.new({
|
15
|
+
likes: {
|
16
|
+
sum: Micropost.pluck(:likes).sum
|
17
|
+
}
|
18
|
+
})
|
19
|
+
expect(aggregations).to eq expected_aggregations
|
20
|
+
end
|
21
|
+
it "multiple aggregations" do
|
22
|
+
hash = {
|
23
|
+
aggregate: {
|
24
|
+
likes: {sum: true}, reposts: {sum: true}, created_at: {sum: true}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
aggregations = HelperClass.new.aggregations(Micropost.all, hash)
|
29
|
+
expected_aggregations = HashWithIndifferentAccess.new({
|
30
|
+
likes: {
|
31
|
+
sum: Micropost.pluck(:likes).sum
|
32
|
+
},
|
33
|
+
reposts: {
|
34
|
+
sum: Micropost.pluck(:reposts).sum
|
35
|
+
},
|
36
|
+
created_at: {}
|
37
|
+
})
|
38
|
+
expect(aggregations).to eq expected_aggregations
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
describe ActiveHashRelation do
|
2
|
+
include Helpers
|
3
|
+
|
4
|
+
context 'associations' do
|
5
|
+
context 'belongs_to' do
|
6
|
+
it "one where clause" do
|
7
|
+
hash = {user: {name: 'Filippos' }}
|
8
|
+
|
9
|
+
query = HelperClass.new.apply_filters(Micropost.all, hash, include_associations: true).to_sql
|
10
|
+
expected_query = q(
|
11
|
+
"SELECT microposts.* FROM microposts",
|
12
|
+
"INNER JOIN users ON users.id = microposts.user_id",
|
13
|
+
"WHERE (users.name = 'Filippos')"
|
14
|
+
)
|
15
|
+
|
16
|
+
expect(strip(query)).to eq expected_query.to_s
|
17
|
+
end
|
18
|
+
it "multiple where clause" do
|
19
|
+
hash = {user: {name: 'Filippos', verified: true }}
|
20
|
+
|
21
|
+
query = HelperClass.new.apply_filters(Micropost.all, hash, include_associations: true).to_sql
|
22
|
+
expected_query = q(
|
23
|
+
"SELECT microposts.* FROM microposts",
|
24
|
+
"INNER JOIN users ON users.id = microposts.user_id",
|
25
|
+
"WHERE (users.name = 'Filippos')",
|
26
|
+
"AND users.verified = 't'"
|
27
|
+
)
|
28
|
+
|
29
|
+
expect(strip(query)).to eq expected_query.to_s
|
30
|
+
end
|
31
|
+
|
32
|
+
it "multiple queries" do
|
33
|
+
date = DateTime.now.utc.to_s
|
34
|
+
hash = {
|
35
|
+
user: {
|
36
|
+
name: {starts_with: 'filippos', with_ilike: true},
|
37
|
+
created_at: {leq: date}
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
query = HelperClass.new.apply_filters(Micropost.all, hash, include_associations: true).to_sql
|
42
|
+
expected_query = q(
|
43
|
+
"SELECT microposts.* FROM microposts",
|
44
|
+
"INNER JOIN users ON users.id = microposts.user_id",
|
45
|
+
"WHERE (users.name ILIKE 'filippos%')",
|
46
|
+
"AND (users.created_at <= '#{date}')"
|
47
|
+
)
|
48
|
+
|
49
|
+
expect(strip(query)).to eq expected_query.to_s
|
50
|
+
end
|
51
|
+
|
52
|
+
it "scope" do
|
53
|
+
hash = {user: {scopes: {unverified: true} }}
|
54
|
+
|
55
|
+
query = HelperClass.new.apply_filters(Micropost.all, hash, include_associations: true).to_sql
|
56
|
+
expected_query = q(
|
57
|
+
"SELECT microposts.* FROM microposts",
|
58
|
+
"INNER JOIN users ON users.id = microposts.user_id",
|
59
|
+
"WHERE users.verified = 'f'"
|
60
|
+
)
|
61
|
+
|
62
|
+
expect(strip(query)).to eq expected_query.to_s
|
63
|
+
end
|
64
|
+
|
65
|
+
it "null" do
|
66
|
+
hash = {user: {name: {null: true} }}
|
67
|
+
|
68
|
+
query = HelperClass.new.apply_filters(Micropost.all, hash, include_associations: true).to_sql
|
69
|
+
expected_query = q(
|
70
|
+
"SELECT microposts.* FROM microposts",
|
71
|
+
"INNER JOIN users ON users.id = microposts.user_id",
|
72
|
+
"WHERE (users.name IS NULL)"
|
73
|
+
)
|
74
|
+
|
75
|
+
expect(strip(query)).to eq expected_query.to_s
|
76
|
+
end
|
77
|
+
|
78
|
+
it "sorting" do
|
79
|
+
hash = {user: {name: 'Filippos', sort: {property: :created_at} }}
|
80
|
+
|
81
|
+
query = HelperClass.new.apply_filters(Micropost.all, hash, include_associations: true).to_sql
|
82
|
+
expected_query = q(
|
83
|
+
"SELECT microposts.* FROM microposts",
|
84
|
+
"INNER JOIN users ON users.id = microposts.user_id",
|
85
|
+
"WHERE (users.name = 'Filippos')",
|
86
|
+
"ORDER BY users.created_at DESC"
|
87
|
+
)
|
88
|
+
|
89
|
+
expect(strip(query)).to eq expected_query.to_s
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
|
@@ -0,0 +1,91 @@
|
|
1
|
+
describe ActiveHashRelation do
|
2
|
+
include Helpers
|
3
|
+
|
4
|
+
context 'associations' do
|
5
|
+
context 'has_many' do
|
6
|
+
it "one where clause" do
|
7
|
+
hash = {microposts: {content: 'Sveavägen 4' }}
|
8
|
+
|
9
|
+
query = HelperClass.new.apply_filters(User.all, hash, include_associations: true).to_sql
|
10
|
+
expected_query = q(
|
11
|
+
"SELECT users.* FROM users",
|
12
|
+
"INNER JOIN microposts ON microposts.user_id = users.id",
|
13
|
+
"WHERE (microposts.content = 'Sveavägen 4')"
|
14
|
+
)
|
15
|
+
|
16
|
+
expect(strip(query)).to eq expected_query.to_s
|
17
|
+
end
|
18
|
+
|
19
|
+
it "multiple where clause" do
|
20
|
+
hash = {microposts: {content: 'Sveavägen 4', created_at: '2017-01-15 16:11:06 UTC' }}
|
21
|
+
|
22
|
+
query = HelperClass.new.apply_filters(User.all, hash, include_associations: true).to_sql
|
23
|
+
expected_query = q(
|
24
|
+
"SELECT users.* FROM users",
|
25
|
+
"INNER JOIN microposts ON microposts.user_id = users.id",
|
26
|
+
"WHERE (microposts.content = 'Sveavägen 4')",
|
27
|
+
"AND microposts.created_at = '2017-01-15 16:11:06 UTC'"
|
28
|
+
)
|
29
|
+
|
30
|
+
expect(strip(query)).to eq expected_query.to_s
|
31
|
+
end
|
32
|
+
|
33
|
+
it "multiple queries" do
|
34
|
+
hash = {microposts: {content: {ends_with: '4'}, created_at: {leq: '2017-01-15 16:11:06 UTC'} }}
|
35
|
+
|
36
|
+
query = HelperClass.new.apply_filters(User.all, hash, include_associations: true).to_sql
|
37
|
+
expected_query = q(
|
38
|
+
"SELECT users.* FROM users",
|
39
|
+
"INNER JOIN microposts ON microposts.user_id = users.id",
|
40
|
+
"WHERE (microposts.content LIKE '%4')",
|
41
|
+
"AND (microposts.created_at <= '2017-01-15 16:11:06 UTC')"
|
42
|
+
)
|
43
|
+
|
44
|
+
expect(strip(query)).to eq expected_query.to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
it "scope" do
|
48
|
+
date = DateTime.now.to_date.to_s
|
49
|
+
hash = {microposts: {scopes: {created_on: [date] }}}
|
50
|
+
|
51
|
+
query = HelperClass.new.apply_filters(User.all, hash, include_associations: true).to_sql
|
52
|
+
expected_query = q(
|
53
|
+
"SELECT users.* FROM users",
|
54
|
+
"INNER JOIN microposts ON microposts.user_id = users.id",
|
55
|
+
"WHERE (date(microposts.created_at) = '#{date}')"
|
56
|
+
)
|
57
|
+
|
58
|
+
expect(strip(query)).to eq expected_query.to_s
|
59
|
+
end
|
60
|
+
|
61
|
+
it "null" do
|
62
|
+
hash = {microposts: {content: {null: true} }}
|
63
|
+
|
64
|
+
query = HelperClass.new.apply_filters(User.all, hash, include_associations: true).to_sql
|
65
|
+
expected_query = q(
|
66
|
+
"SELECT users.* FROM users",
|
67
|
+
"INNER JOIN microposts ON microposts.user_id = users.id",
|
68
|
+
"WHERE (microposts.content IS NULL)"
|
69
|
+
)
|
70
|
+
|
71
|
+
expect(strip(query)).to eq expected_query.to_s
|
72
|
+
end
|
73
|
+
|
74
|
+
it "sorting" do
|
75
|
+
hash = {microposts: {content: 'Sveavägen 4', sort: {property: :created_at} }}
|
76
|
+
|
77
|
+
query = HelperClass.new.apply_filters(User.all, hash, include_associations: true).to_sql
|
78
|
+
expected_query = q(
|
79
|
+
"SELECT users.* FROM users",
|
80
|
+
"INNER JOIN microposts ON microposts.user_id = users.id",
|
81
|
+
"WHERE (microposts.content = 'Sveavägen 4')",
|
82
|
+
"ORDER BY microposts.created_at DESC"
|
83
|
+
)
|
84
|
+
|
85
|
+
expect(strip(query)).to eq expected_query.to_s
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
|