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
|
require 'abstract_unit'
require 'fixtures/post'
require 'fixtures/comment'
require 'fixtures/author'
require 'fixtures/category'
require 'fixtures/categorization'
require 'fixtures/company'
require 'fixtures/topic'
require 'fixtures/reply'
require 'fixtures/developer'
require 'fixtures/project'
class ArJoinsTest < Test::Unit::TestCase
fixtures :authors, :posts, :comments, :categories, :categories_posts, :people,
:developers, :projects, :developers_projects,
:categorizations, :companies, :accounts, :topics
def test_ar_joins
authors = Author.find(:all, :joins => :posts, :conditions => ['posts.type = ?', "Post"])
assert_not_equal(0 , authors.length)
authors.each do |author|
assert !(author.send(:instance_variables).include? "@posts")
assert(!author.readonly?, "non-string join value produced read-only result.")
end
end
def test_ar_joins_with_cascaded_two_levels
authors = Author.find(:all, :joins=>{:posts=>:comments})
assert_equal(2, authors.length)
authors.each do |author|
assert !(author.send(:instance_variables).include? "@posts")
assert(!author.readonly?, "non-string join value produced read-only result.")
end
authors = Author.find(:all, :joins=>{:posts=>:comments}, :conditions => ["comments.body = ?", "go crazy" ])
assert_equal(1, authors.length)
authors.each do |author|
assert !(author.send(:instance_variables).include? "@posts")
assert(!author.readonly?, "non-string join value produced read-only result.")
end
end
def test_ar_joins_with_complex_conditions
authors = Author.find(:all, :joins=>{:posts=>[:comments, :categories]},
:conditions => ["categories.name = ? AND posts.title = ?", "General", "So I was thinking"]
)
assert_equal(1, authors.length)
authors.each do |author|
assert !(author.send(:instance_variables).include? "@posts")
assert(!author.readonly?, "non-string join value produced read-only result.")
end
assert_equal("David", authors.first.name)
end
def test_ar_join_with_has_many_and_limit_and_scoped_and_explicit_conditions
Post.with_scope(:find => { :conditions => "1=1" }) do
posts = authors(:david).posts.find(:all,
:joins => :comments,
:conditions => "comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment'",
:limit => 2
)
assert_equal 2, posts.size
count = Post.count(
:joins => [ :comments, :author ],
:conditions => "authors.name = 'David' AND (comments.body like 'Normal%' OR comments.#{QUOTED_TYPE}= 'SpecialComment')",
:limit => 2
)
assert_equal count, posts.size
end
end
def test_ar_join_with_scoped_order_using_association_limiting_without_explicit_scope
posts_with_explicit_order = Post.find(:all, :conditions => 'comments.id is not null', :joins => :comments, :order => 'posts.id DESC', :limit => 2)
posts_with_scoped_order = Post.with_scope(:find => {:order => 'posts.id DESC'}) do
Post.find(:all, :conditions => 'comments.id is not null', :joins => :comments, :limit => 2)
end
assert_equal posts_with_explicit_order, posts_with_scoped_order
end
def test_scoped_find_include
# with the include, will retrieve only developers for the given project
scoped_developers = Developer.with_scope(:find => { :joins => :projects }) do
Developer.find(:all, :conditions => 'projects.id = 2')
end
assert scoped_developers.include?(developers(:david))
assert !scoped_developers.include?(developers(:jamis))
assert_equal 1, scoped_developers.size
end
def test_nested_scoped_find_ar_join
Developer.with_scope(:find => { :joins => :projects }) do
Developer.with_scope(:find => { :conditions => "projects.id = 2" }) do
assert_equal('David', Developer.find(:first).name)
end
end
end
def test_nested_scoped_find_merged_ar_join
# :include's remain unique and don't "double up" when merging
Developer.with_scope(:find => { :joins => :projects, :conditions => "projects.id = 2" }) do
Developer.with_scope(:find => { :joins => :projects }) do
assert_equal 1, Developer.instance_eval('current_scoped_methods')[:find][:ar_joins].length
assert_equal('David', Developer.find(:first).name)
end
end
# the nested scope doesn't remove the first :include
Developer.with_scope(:find => { :joins => :projects, :conditions => "projects.id = 2" }) do
Developer.with_scope(:find => { :joins => [] }) do
assert_equal 1, Developer.instance_eval('current_scoped_methods')[:find][:ar_joins].length
assert_equal('David', Developer.find(:first).name)
end
end
# mixing array and symbol include's will merge correctly
Developer.with_scope(:find => { :joins => [:projects], :conditions => "projects.id = 2" }) do
Developer.with_scope(:find => { :joins => :projects }) do
assert_equal 1, Developer.instance_eval('current_scoped_methods')[:find][:ar_joins].length
assert_equal('David', Developer.find(:first).name)
end
end
end
def test_nested_scoped_find_replace_include
Developer.with_scope(:find => { :joins => :projects }) do
Developer.with_exclusive_scope(:find => { :joins => [] }) do
assert_equal 0, Developer.instance_eval('current_scoped_methods')[:find][:ar_joins].length
end
end
end
#
# Calculations
#
def test_count_with_ar_joins
assert_equal(2, Author.count(:joins => :posts, :conditions => ['posts.type = ?', "Post"]))
assert_equal(1, Author.count(:joins => :posts, :conditions => ['posts.type = ?', "SpecialPost"]))
end
def test_should_get_maximum_of_field_with_joins
assert_equal 50, Account.maximum(:credit_limit, :joins=> :firm, :conditions => "companies.name != 'Summit'")
end
def test_should_get_maximum_of_field_with_scoped_include
Account.with_scope :find => { :joins => :firm, :conditions => "companies.name != 'Summit'" } do
assert_equal 50, Account.maximum(:credit_limit)
end
end
def test_should_not_modify_options_when_using_ar_joins_on_count
options = {:conditions => 'companies.id > 1', :joins => :firm}
options_copy = options.dup
Account.count(:all, options)
assert_equal options_copy, options
end
end
|