-
Notifications
You must be signed in to change notification settings - Fork 3
/
outer_join_spec.rb
161 lines (131 loc) · 5.58 KB
/
outer_join_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
require "spec_helper"
class Product < ActiveRecord::Base
belongs_to :category
belongs_to :site
has_many :line_items
has_many :baskets, :through => :line_items
has_many :discounts, :through => :line_items
has_and_belongs_to_many :tags
has_one :image
end
class LineItem < ActiveRecord::Base
belongs_to :basket
belongs_to :product
has_many :discounts
end
class Image < ActiveRecord::Base
belongs_to :product
end
class Discount < ActiveRecord::Base
belongs_to :line_item
end
class Basket < ActiveRecord::Base; end
class Category < ActiveRecord::Base; end
class Site < ActiveRecord::Base; end
class Tag < ActiveRecord::Base; end
describe ActiveRecord::Base do
describe ".outer_join" do
context "with belongs_to" do
it "performs an outer join" do
category1 = Category.create! :name => "Shoes"
category2 = Category.create! :name => "Shirts"
product1 = Product.create! :category => category1
product2 = Product.create! :category => category2
product3 = Product.create! :published => true
query = Product.outer_join(:category).where("categories.name = ? OR products.published = ?", "Shirts", true)
query.all.should =~ [product2, product3]
end
it "joins several associations" do
site1 = Site.create! :name => "Elabs"
category1 = Category.create! :name => "Shoes"
category2 = Category.create! :name => "Shirts"
product1 = Product.create! :category => category1
product2 = Product.create! :category => category2
product3 = Product.create! :published => true
product4 = Product.create! :site => site1
query = Product.outer_join(:category, :site).where("sites.name = ? OR categories.name = ? OR products.published = ?", "Elabs", "Shirts", true)
query.all.should =~ [product2, product3, product4]
end
end
context "with has_one" do
it "performs an outer join" do
product1 = Product.create!
product2 = Product.create!
product3 = Product.create! :published => true
product4 = Product.create!
Image.create! :highres => true, :product => product1
Image.create! :product => product2
query = Product.outer_join(:image).where("images.highres = ? OR products.published = ?", true, true)
query.all.should =~ [product1, product3]
end
end
context "with has_many" do
it "performs an outer join" do
product1 = Product.create!
product2 = Product.create!
product3 = Product.create! :published => true
product4 = Product.create!
LineItem.create! :price => 4, :product => product1
LineItem.create! :product => product2
query = Product.outer_join(:line_items).where("line_items.price = ? OR products.published = ?", 4, true)
query.all.should =~ [product1, product3]
end
end
context "with has_and_belongs_to_many" do
it "performs an outer join" do
red = Tag.create! :name => "Red"
blue = Tag.create! :name => "Blue"
product1 = Product.create!
product2 = Product.create! :tags => [red]
product3 = Product.create! :tags => [red, blue]
product4 = Product.create! :published => true
query = Product.outer_join(:tags).where("tags.name = ? OR products.published = ?", "Red", true)
query.all.should =~ [product2, product3, product4]
end
end
context "with has_many :through" do
it "performs an outer join" do
product1 = Product.create!
product2 = Product.create!
product3 = Product.create! :published => true
product4 = Product.create!
basket1 = Basket.create! :purchased => true
basket2 = Basket.create! :purchased => false
LineItem.create! :product => product1, :basket => basket1
LineItem.create! :product => product2, :basket => basket2
LineItem.create! :product => product3
query = Product.outer_join(:baskets).where("baskets.purchased = ? OR products.published = ?", true, true)
query.all.should =~ [product1, product3]
end
end
context "with nested associations" do
it "allows hashes" do
product1 = Product.create!
product2 = Product.create!
product3 = Product.create! :published => true
product4 = Product.create!
basket1 = Basket.create! :purchased => true
basket2 = Basket.create! :purchased => false
LineItem.create! :product => product1, :basket => basket1
LineItem.create! :product => product2, :basket => basket2
LineItem.create! :product => product3
query = Product.outer_join(:line_items => :basket).where("baskets.purchased = ? OR products.published = ?", true, true)
query.all.should =~ [product1, product3]
end
it "allows hashes with arrays" do
product1 = Product.create!
product2 = Product.create!
product3 = Product.create! :published => true
product4 = Product.create!
basket1 = Basket.create! :purchased => true
basket2 = Basket.create! :purchased => false
line_item1 = LineItem.create! :product => product1, :basket => basket1
line_item2 = LineItem.create! :product => product2, :basket => basket2
line_item3 = LineItem.create! :product => product4
Discount.create! :line_item => line_item3, :percentage => 80
query = Product.outer_join(:line_items => [:basket, :discounts]).where("baskets.purchased = ? OR products.published = ? OR discounts.percentage > ?", true, true, 50)
query.all.should =~ [product1, product3, product4]
end
end
end
end