/
association_conditions_spec.rb
145 lines (118 loc) · 7.24 KB
/
association_conditions_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
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
describe "Association Conditions" do
it "should create a named scope" do
Company.users_username_like("bjohnson").proxy_options.should == User.username_like("bjohnson").proxy_options.merge(:joins => :users)
end
it "should create a deep named scope" do
Company.users_orders_total_greater_than(10).proxy_options.should == Order.total_greater_than(10).proxy_options.merge(:joins => {:users => :orders})
end
it "should allow the use of foreign pre-existing named scopes" do
User.named_scope :uname, lambda { |value| {:conditions => ["users.username = ?", value]} }
Company.users_uname("bjohnson").proxy_options.should == User.uname("bjohnson").proxy_options.merge(:joins => :users)
end
it "should allow the use of deep foreign pre-existing named scopes" do
pending
Order.named_scope :big_id, :conditions => "orders.id > 100"
Company.users_orders_big_id.proxy_options.should == Order.big_id.proxy_options.merge(:joins => {:users => :orders})
end
it "should allow the use of foreign pre-existing alias scopes" do
User.alias_scope :username_has, lambda { |value| User.username_like(value) }
Company.users_username_has("bjohnson").proxy_options.should == User.username_has("bjohnson").proxy_options.merge(:joins => :users)
end
it "should not raise errors for scopes that don't return anything" do
User.alias_scope :blank_scope, lambda { |value| }
Company.users_blank_scope("bjohnson").proxy_options.should == {:joins => :users}
end
it "should ignore polymorphic associations" do
lambda { Fee.owner_created_at_gt(Time.now) }.should raise_error(NoMethodError)
end
it "should not allow named scopes on non existent association columns" do
lambda { User.users_whatever_like("bjohnson") }.should raise_error(NoMethodError)
end
it "should not allow named scopes on non existent deep association columns" do
lambda { User.users_orders_whatever_like("bjohnson") }.should raise_error(NoMethodError)
end
it "should allow named scopes to be called multiple times and reflect the value passed" do
Company.users_username_like("bjohnson").proxy_options.should == User.username_like("bjohnson").proxy_options.merge(:joins => :users)
Company.users_username_like("thunt").proxy_options.should == User.username_like("thunt").proxy_options.merge(:joins => :users)
end
it "should allow deep named scopes to be called multiple times and reflect the value passed" do
Company.users_orders_total_greater_than(10).proxy_options.should == Order.total_greater_than(10).proxy_options.merge(:joins => {:users => :orders})
Company.users_orders_total_greater_than(20).proxy_options.should == Order.total_greater_than(20).proxy_options.merge(:joins => {:users => :orders})
end
it "should have an arity of 1 if the underlying scope has an arity of 1" do
Company.users_orders_total_greater_than(10)
Company.named_scope_arity("users_orders_total_greater_than").should == Order.named_scope_arity("total_greater_than")
end
it "should have an arity of nil if the underlying scope has an arity of nil" do
Company.users_orders_total_null
Company.named_scope_arity("users_orders_total_null").should == Order.named_scope_arity("total_null")
end
it "should have an arity of -1 if the underlying scope has an arity of -1" do
Company.users_id_equals_any
Company.named_scope_arity("users_id_equals_any").should == User.named_scope_arity("id_equals_any")
end
it "should allow aliases" do
Company.users_username_contains("bjohnson").proxy_options.should == User.username_contains("bjohnson").proxy_options.merge(:joins => :users)
end
it "should allow deep aliases" do
Company.users_orders_total_gt(10).proxy_options.should == Order.total_gt(10).proxy_options.merge(:joins => {:users => :orders})
end
it "should include optional associations" do
pending # this is a problem with using inner joins and left outer joins
Company.create
company = Company.create
user = company.users.create
order = user.orders.create(:total => 20, :taxes => 3)
Company.ascend_by_users_orders_total.all.should == Company.all
end
it "should not create the same join twice" do
company = Company.create
user = company.users.create
order = user.orders.create(:total => 20, :taxes => 3)
Company.users_orders_total_gt(10).users_orders_taxes_lt(5).ascend_by_users_orders_total.all.should == Company.all
end
it "should not create the same join twice when traveling through the duplicate join" do
Company.users_username_like("bjohnson").users_orders_total_gt(100).all.should == Company.all
end
it "should not create the same join twice when traveling through the duplicate join 2" do
Company.users_orders_total_gt(100).users_orders_line_items_price_gt(20).all.should == Company.all
end
it "should allow the use of :include when a join was created" do
company = Company.create
user = company.users.create
order = user.orders.create(:total => 20, :taxes => 3)
Company.users_orders_total_gt(10).users_orders_taxes_lt(5).ascend_by_users_orders_total.all(:include => :users).should == Company.all
end
it "should allow the use of deep :include when a join was created" do
company = Company.create
user = company.users.create
order = user.orders.create(:total => 20, :taxes => 3)
Company.users_orders_total_gt(10).users_orders_taxes_lt(5).ascend_by_users_orders_total.all(:include => {:users => :orders}).should == Company.all
end
it "should allow the use of :include when traveling through the duplicate join" do
company = Company.create
user = company.users.create(:username => "bjohnson")
order = user.orders.create(:total => 20, :taxes => 3)
Company.users_username_like("bjohnson").users_orders_taxes_lt(5).ascend_by_users_orders_total.all(:include => :users).should == Company.all
end
it "should allow the use of deep :include when traveling through the duplicate join" do
company = Company.create
user = company.users.create(:username => "bjohnson")
order = user.orders.create(:total => 20, :taxes => 3)
Company.users_orders_taxes_lt(50).ascend_by_users_orders_total.all(:include => {:users => :orders}).should == Company.all
end
it "should automatically add string joins if the association condition is using strings" do
User.named_scope(:orders_big_id, :joins => User.inner_joins(:orders))
Company.users_orders_big_id.proxy_options.should == {:joins=>[" INNER JOIN \"users\" ON users.company_id = companies.id ", " INNER JOIN \"orders\" ON orders.user_id = users.id "]}
end
it "should order the join statements ascending by the fieldnames so that we don't get double joins where the only difference is that the order of the fields is different" do
company = Company.create
user = company.users.create(:company_id => company.id)
company.users.company_id_eq(company.id).should == [user]
end
it "should sanitize the scope on a foreign model instead of passing the raw options back to the original" do
Company.named_scope(:users_count_10, :conditions => {:users_count => 10})
User.company_users_count_10.proxy_options.should == {:conditions => "\"users\".\"users_count\" = 10", :joins => :company}
end
end