ibm_db 2.5.26-universal-darwin-14 → 2.6.1-universal-darwin-14
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/CHANGES +11 -0
- data/MANIFEST +14 -14
- data/README +225 -225
- data/ext/Makefile.nt32 +181 -181
- data/ext/Makefile.nt32.191 +212 -212
- data/ext/extconf.rb +264 -261
- data/ext/extconf_MacOS.rb +269 -0
- data/ext/ibm_db.c +11879 -11793
- data/ext/ruby_ibm_db.h +241 -240
- data/ext/ruby_ibm_db_cli.c +851 -845
- data/ext/ruby_ibm_db_cli.h +500 -489
- data/init.rb +41 -41
- data/lib/IBM_DB.rb +27 -19
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +3339 -3289
- data/lib/active_record/connection_adapters/ibmdb_adapter.rb +1 -1
- data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -328
- data/test/cases/adapter_test.rb +207 -207
- data/test/cases/associations/belongs_to_associations_test.rb +711 -711
- data/test/cases/associations/cascaded_eager_loading_test.rb +181 -181
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +851 -851
- data/test/cases/associations/join_model_test.rb +743 -743
- data/test/cases/attribute_methods_test.rb +822 -822
- data/test/cases/base_test.rb +2133 -2133
- data/test/cases/calculations_test.rb +482 -482
- data/test/cases/migration_test.rb +2408 -2408
- data/test/cases/persistence_test.rb +642 -642
- data/test/cases/query_cache_test.rb +257 -257
- data/test/cases/relations_test.rb +1182 -1182
- data/test/cases/schema_dumper_test.rb +256 -256
- data/test/cases/transaction_callbacks_test.rb +300 -300
- data/test/cases/validations/uniqueness_validation_test.rb +299 -299
- data/test/cases/xml_serialization_test.rb +408 -408
- data/test/config.yml +154 -154
- data/test/connections/native_ibm_db/connection.rb +43 -43
- data/test/ibm_db_test.rb +24 -24
- data/test/models/warehouse_thing.rb +4 -4
- data/test/schema/schema.rb +751 -751
- metadata +6 -8
- data/lib/linux/rb18x/ibm_db.bundle +0 -0
- data/lib/linux/rb19x/ibm_db.bundle +0 -0
- data/lib/linux/rb20x/ibm_db.bundle +0 -0
- data/lib/linux/rb21x/ibm_db.bundle +0 -0
@@ -1,181 +1,181 @@
|
|
1
|
-
require "cases/helper"
|
2
|
-
require 'models/post'
|
3
|
-
require 'models/comment'
|
4
|
-
require 'models/author'
|
5
|
-
require 'models/categorization'
|
6
|
-
require 'models/category'
|
7
|
-
require 'models/company'
|
8
|
-
require 'models/topic'
|
9
|
-
require 'models/reply'
|
10
|
-
require 'models/person'
|
11
|
-
require 'models/vertex'
|
12
|
-
require 'models/edge'
|
13
|
-
|
14
|
-
class CascadedEagerLoadingTest < ActiveRecord::TestCase
|
15
|
-
fixtures :authors, :mixins, :companies, :posts, :topics, :accounts, :comments,
|
16
|
-
:categorizations, :people, :categories, :edges, :vertices
|
17
|
-
|
18
|
-
def test_eager_association_loading_with_cascaded_two_levels
|
19
|
-
authors = Author.find(:all, :include=>{:posts=>:comments}, :order=>"authors.id")
|
20
|
-
assert_equal 3, authors.size
|
21
|
-
assert_equal 5, authors[0].posts.size
|
22
|
-
assert_equal 3, authors[1].posts.size
|
23
|
-
assert_equal 10, authors[0].posts.collect{|post| post.comments.size }.inject(0){|sum,i| sum+i}
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_eager_association_loading_with_cascaded_two_levels_and_one_level
|
27
|
-
authors = Author.find(:all, :include=>[{:posts=>:comments}, :categorizations], :order=>"authors.id")
|
28
|
-
assert_equal 3, authors.size
|
29
|
-
assert_equal 5, authors[0].posts.size
|
30
|
-
assert_equal 3, authors[1].posts.size
|
31
|
-
assert_equal 10, authors[0].posts.collect{|post| post.comments.size }.inject(0){|sum,i| sum+i}
|
32
|
-
assert_equal 1, authors[0].categorizations.size
|
33
|
-
assert_equal 2, authors[1].categorizations.size
|
34
|
-
end
|
35
|
-
|
36
|
-
def test_eager_association_loading_with_hmt_does_not_table_name_collide_when_joining_associations
|
37
|
-
assert_nothing_raised do
|
38
|
-
Author.joins(:posts).eager_load(:comments).where(:posts => {:taggings_count => 1}).all
|
39
|
-
end
|
40
|
-
authors = Author.joins(:posts).eager_load(:comments).where(:posts => {:taggings_count => 1}).all
|
41
|
-
assert_equal 1, assert_no_queries { authors.size }
|
42
|
-
assert_equal 10, assert_no_queries { authors[0].comments.size }
|
43
|
-
end
|
44
|
-
|
45
|
-
def test_eager_association_loading_grafts_stashed_associations_to_correct_parent
|
46
|
-
assert_nothing_raised do
|
47
|
-
Person.eager_load(:primary_contact => :primary_contact).where('primary_contacts_people_2.first_name = ?', 'Susan').order('people.id').all
|
48
|
-
end
|
49
|
-
assert_equal people(:michael), Person.eager_load(:primary_contact => :primary_contact).where('primary_contacts_people_2.first_name = ?', 'Susan').order('people.id').first
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_cascaded_eager_association_loading_with_join_for_count
|
53
|
-
categories = Category.joins(:categorizations).includes([{:posts=>:comments}, :authors])
|
54
|
-
|
55
|
-
assert_nothing_raised do
|
56
|
-
assert_equal 4, categories.count
|
57
|
-
assert_equal 4, categories.all.count
|
58
|
-
assert_equal 3, categories.count(:distinct => true)
|
59
|
-
assert_equal 3, categories.all.uniq.size # Must uniq since instantiating with inner joins will get dupes
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def test_cascaded_eager_association_loading_with_duplicated_includes
|
64
|
-
categories = Category.includes(:categorizations).includes(:categorizations => :author).where("categorizations.id is not null")
|
65
|
-
assert_nothing_raised do
|
66
|
-
assert_equal 3, categories.count
|
67
|
-
assert_equal 3, categories.all.size
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def test_cascaded_eager_association_loading_with_twice_includes_edge_cases
|
72
|
-
categories = Category.includes(:categorizations => :author).includes(:categorizations => :post).where("posts.id is not null")
|
73
|
-
assert_nothing_raised do
|
74
|
-
assert_equal 3, categories.count
|
75
|
-
assert_equal 3, categories.all.size
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def test_eager_association_loading_with_join_for_count
|
80
|
-
authors = Author.joins(:special_posts).includes([:posts, :categorizations])
|
81
|
-
|
82
|
-
assert_nothing_raised { authors.count }
|
83
|
-
assert_queries(3) { authors.all }
|
84
|
-
end
|
85
|
-
|
86
|
-
def test_eager_association_loading_with_cascaded_two_levels_with_two_has_many_associations
|
87
|
-
authors = Author.find(:all, :include=>{:posts=>[:comments, :categorizations]}, :order=>"authors.id")
|
88
|
-
assert_equal 3, authors.size
|
89
|
-
assert_equal 5, authors[0].posts.size
|
90
|
-
assert_equal 3, authors[1].posts.size
|
91
|
-
assert_equal 10, authors[0].posts.collect{|post| post.comments.size }.inject(0){|sum,i| sum+i}
|
92
|
-
end
|
93
|
-
|
94
|
-
def test_eager_association_loading_with_cascaded_two_levels_and_self_table_reference
|
95
|
-
authors = Author.find(:all, :include=>{:posts=>[:comments, :author]}, :order=>"authors.id")
|
96
|
-
assert_equal 3, authors.size
|
97
|
-
assert_equal 5, authors[0].posts.size
|
98
|
-
assert_equal authors(:david).name, authors[0].name
|
99
|
-
assert_equal [authors(:david).name], authors[0].posts.collect{|post| post.author.name}.uniq
|
100
|
-
end
|
101
|
-
|
102
|
-
def test_eager_association_loading_with_cascaded_two_levels_with_condition
|
103
|
-
authors = Author.find(:all, :include=>{:posts=>:comments}, :conditions=>"authors.id=1", :order=>"authors.id")
|
104
|
-
assert_equal 1, authors.size
|
105
|
-
assert_equal 5, authors[0].posts.size
|
106
|
-
end
|
107
|
-
|
108
|
-
def test_eager_association_loading_with_cascaded_three_levels_by_ping_pong
|
109
|
-
firms = Firm.find(:all, :include=>{:account=>{:firm=>:account}}, :order=>"companies.id")
|
110
|
-
assert_equal 2, firms.size
|
111
|
-
assert_equal firms.first.account, firms.first.account.firm.account
|
112
|
-
assert_equal companies(:first_firm).account, assert_no_queries { firms.first.account.firm.account }
|
113
|
-
assert_equal companies(:first_firm).account.firm.account, assert_no_queries { firms.first.account.firm.account }
|
114
|
-
end
|
115
|
-
|
116
|
-
def test_eager_association_loading_with_has_many_sti
|
117
|
-
topics = Topic.find(:all, :include => :replies, :order => 'topics.id')
|
118
|
-
first, second, = topics(:first).replies.size, topics(:second).replies.size
|
119
|
-
assert_no_queries do
|
120
|
-
assert_equal first, topics[0].replies.size
|
121
|
-
assert_equal second, topics[1].replies.size
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
def test_eager_association_loading_with_has_many_sti_and_subclasses
|
126
|
-
silly = SillyReply.new(:title => "gaga", :content => "boo-boo", :parent_id => 1)
|
127
|
-
silly.parent_id = 1
|
128
|
-
assert silly.save
|
129
|
-
|
130
|
-
topics = Topic.find(:all, :include => :replies, :order => 'topics.id, replies_topics.id')
|
131
|
-
assert_no_queries do
|
132
|
-
assert_equal 2, topics[0].replies.size
|
133
|
-
assert_equal 0, topics[1].replies.size
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
def test_eager_association_loading_with_belongs_to_sti
|
138
|
-
replies = Reply.find(:all, :include => :topic, :order => 'topics.id')
|
139
|
-
assert replies.include?(topics(:second))
|
140
|
-
assert !replies.include?(topics(:first))
|
141
|
-
assert_equal topics(:first), assert_no_queries { replies.first.topic }
|
142
|
-
end
|
143
|
-
|
144
|
-
unless current_adapter?(:IBM_DBAdapter)
|
145
|
-
def test_eager_association_loading_with_multiple_stis_and_order
|
146
|
-
author = Author.find(:first, :include => { :posts => [ :special_comments , :very_special_comment ] }, :order => ['authors.name', 'comments.body', 'very_special_comments_posts.body'], :conditions => 'posts.id = 4')
|
147
|
-
assert_equal authors(:david), author
|
148
|
-
assert_no_queries do
|
149
|
-
author.posts.first.special_comments
|
150
|
-
author.posts.first.very_special_comment
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
def test_eager_association_loading_of_stis_with_multiple_references
|
156
|
-
authors = Author.find(:all, :include => { :posts => { :special_comments => { :post => [ :special_comments, :very_special_comment ] } } }, :order => 'comments.body, very_special_comments_posts.body', :conditions => 'posts.id = 4')
|
157
|
-
assert_equal [authors(:david)], authors
|
158
|
-
assert_no_queries do
|
159
|
-
authors.first.posts.first.special_comments.first.post.special_comments
|
160
|
-
authors.first.posts.first.special_comments.first.post.very_special_comment
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
def test_eager_association_loading_where_first_level_returns_nil
|
165
|
-
authors = Author.find(:all, :include => {:post_about_thinking => :comments}, :order => 'authors.id DESC')
|
166
|
-
assert_equal [authors(:bob), authors(:mary), authors(:david)], authors
|
167
|
-
assert_no_queries do
|
168
|
-
authors[2].post_about_thinking.comments.first
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
def test_eager_association_loading_with_recursive_cascading_four_levels_has_many_through
|
173
|
-
source = Vertex.find(:first, :include=>{:sinks=>{:sinks=>{:sinks=>:sinks}}}, :order => 'vertices.id')
|
174
|
-
assert_equal vertices(:vertex_4), assert_no_queries { source.sinks.first.sinks.first.sinks.first }
|
175
|
-
end
|
176
|
-
|
177
|
-
def test_eager_association_loading_with_recursive_cascading_four_levels_has_and_belongs_to_many
|
178
|
-
sink = Vertex.find(:first, :include=>{:sources=>{:sources=>{:sources=>:sources}}}, :order => 'vertices.id DESC')
|
179
|
-
assert_equal vertices(:vertex_1), assert_no_queries { sink.sources.first.sources.first.sources.first.sources.first }
|
180
|
-
end
|
181
|
-
end
|
1
|
+
require "cases/helper"
|
2
|
+
require 'models/post'
|
3
|
+
require 'models/comment'
|
4
|
+
require 'models/author'
|
5
|
+
require 'models/categorization'
|
6
|
+
require 'models/category'
|
7
|
+
require 'models/company'
|
8
|
+
require 'models/topic'
|
9
|
+
require 'models/reply'
|
10
|
+
require 'models/person'
|
11
|
+
require 'models/vertex'
|
12
|
+
require 'models/edge'
|
13
|
+
|
14
|
+
class CascadedEagerLoadingTest < ActiveRecord::TestCase
|
15
|
+
fixtures :authors, :mixins, :companies, :posts, :topics, :accounts, :comments,
|
16
|
+
:categorizations, :people, :categories, :edges, :vertices
|
17
|
+
|
18
|
+
def test_eager_association_loading_with_cascaded_two_levels
|
19
|
+
authors = Author.find(:all, :include=>{:posts=>:comments}, :order=>"authors.id")
|
20
|
+
assert_equal 3, authors.size
|
21
|
+
assert_equal 5, authors[0].posts.size
|
22
|
+
assert_equal 3, authors[1].posts.size
|
23
|
+
assert_equal 10, authors[0].posts.collect{|post| post.comments.size }.inject(0){|sum,i| sum+i}
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_eager_association_loading_with_cascaded_two_levels_and_one_level
|
27
|
+
authors = Author.find(:all, :include=>[{:posts=>:comments}, :categorizations], :order=>"authors.id")
|
28
|
+
assert_equal 3, authors.size
|
29
|
+
assert_equal 5, authors[0].posts.size
|
30
|
+
assert_equal 3, authors[1].posts.size
|
31
|
+
assert_equal 10, authors[0].posts.collect{|post| post.comments.size }.inject(0){|sum,i| sum+i}
|
32
|
+
assert_equal 1, authors[0].categorizations.size
|
33
|
+
assert_equal 2, authors[1].categorizations.size
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_eager_association_loading_with_hmt_does_not_table_name_collide_when_joining_associations
|
37
|
+
assert_nothing_raised do
|
38
|
+
Author.joins(:posts).eager_load(:comments).where(:posts => {:taggings_count => 1}).all
|
39
|
+
end
|
40
|
+
authors = Author.joins(:posts).eager_load(:comments).where(:posts => {:taggings_count => 1}).all
|
41
|
+
assert_equal 1, assert_no_queries { authors.size }
|
42
|
+
assert_equal 10, assert_no_queries { authors[0].comments.size }
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_eager_association_loading_grafts_stashed_associations_to_correct_parent
|
46
|
+
assert_nothing_raised do
|
47
|
+
Person.eager_load(:primary_contact => :primary_contact).where('primary_contacts_people_2.first_name = ?', 'Susan').order('people.id').all
|
48
|
+
end
|
49
|
+
assert_equal people(:michael), Person.eager_load(:primary_contact => :primary_contact).where('primary_contacts_people_2.first_name = ?', 'Susan').order('people.id').first
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_cascaded_eager_association_loading_with_join_for_count
|
53
|
+
categories = Category.joins(:categorizations).includes([{:posts=>:comments}, :authors])
|
54
|
+
|
55
|
+
assert_nothing_raised do
|
56
|
+
assert_equal 4, categories.count
|
57
|
+
assert_equal 4, categories.all.count
|
58
|
+
assert_equal 3, categories.count(:distinct => true)
|
59
|
+
assert_equal 3, categories.all.uniq.size # Must uniq since instantiating with inner joins will get dupes
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_cascaded_eager_association_loading_with_duplicated_includes
|
64
|
+
categories = Category.includes(:categorizations).includes(:categorizations => :author).where("categorizations.id is not null")
|
65
|
+
assert_nothing_raised do
|
66
|
+
assert_equal 3, categories.count
|
67
|
+
assert_equal 3, categories.all.size
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_cascaded_eager_association_loading_with_twice_includes_edge_cases
|
72
|
+
categories = Category.includes(:categorizations => :author).includes(:categorizations => :post).where("posts.id is not null")
|
73
|
+
assert_nothing_raised do
|
74
|
+
assert_equal 3, categories.count
|
75
|
+
assert_equal 3, categories.all.size
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_eager_association_loading_with_join_for_count
|
80
|
+
authors = Author.joins(:special_posts).includes([:posts, :categorizations])
|
81
|
+
|
82
|
+
assert_nothing_raised { authors.count }
|
83
|
+
assert_queries(3) { authors.all }
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_eager_association_loading_with_cascaded_two_levels_with_two_has_many_associations
|
87
|
+
authors = Author.find(:all, :include=>{:posts=>[:comments, :categorizations]}, :order=>"authors.id")
|
88
|
+
assert_equal 3, authors.size
|
89
|
+
assert_equal 5, authors[0].posts.size
|
90
|
+
assert_equal 3, authors[1].posts.size
|
91
|
+
assert_equal 10, authors[0].posts.collect{|post| post.comments.size }.inject(0){|sum,i| sum+i}
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_eager_association_loading_with_cascaded_two_levels_and_self_table_reference
|
95
|
+
authors = Author.find(:all, :include=>{:posts=>[:comments, :author]}, :order=>"authors.id")
|
96
|
+
assert_equal 3, authors.size
|
97
|
+
assert_equal 5, authors[0].posts.size
|
98
|
+
assert_equal authors(:david).name, authors[0].name
|
99
|
+
assert_equal [authors(:david).name], authors[0].posts.collect{|post| post.author.name}.uniq
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_eager_association_loading_with_cascaded_two_levels_with_condition
|
103
|
+
authors = Author.find(:all, :include=>{:posts=>:comments}, :conditions=>"authors.id=1", :order=>"authors.id")
|
104
|
+
assert_equal 1, authors.size
|
105
|
+
assert_equal 5, authors[0].posts.size
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_eager_association_loading_with_cascaded_three_levels_by_ping_pong
|
109
|
+
firms = Firm.find(:all, :include=>{:account=>{:firm=>:account}}, :order=>"companies.id")
|
110
|
+
assert_equal 2, firms.size
|
111
|
+
assert_equal firms.first.account, firms.first.account.firm.account
|
112
|
+
assert_equal companies(:first_firm).account, assert_no_queries { firms.first.account.firm.account }
|
113
|
+
assert_equal companies(:first_firm).account.firm.account, assert_no_queries { firms.first.account.firm.account }
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_eager_association_loading_with_has_many_sti
|
117
|
+
topics = Topic.find(:all, :include => :replies, :order => 'topics.id')
|
118
|
+
first, second, = topics(:first).replies.size, topics(:second).replies.size
|
119
|
+
assert_no_queries do
|
120
|
+
assert_equal first, topics[0].replies.size
|
121
|
+
assert_equal second, topics[1].replies.size
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_eager_association_loading_with_has_many_sti_and_subclasses
|
126
|
+
silly = SillyReply.new(:title => "gaga", :content => "boo-boo", :parent_id => 1)
|
127
|
+
silly.parent_id = 1
|
128
|
+
assert silly.save
|
129
|
+
|
130
|
+
topics = Topic.find(:all, :include => :replies, :order => 'topics.id, replies_topics.id')
|
131
|
+
assert_no_queries do
|
132
|
+
assert_equal 2, topics[0].replies.size
|
133
|
+
assert_equal 0, topics[1].replies.size
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_eager_association_loading_with_belongs_to_sti
|
138
|
+
replies = Reply.find(:all, :include => :topic, :order => 'topics.id')
|
139
|
+
assert replies.include?(topics(:second))
|
140
|
+
assert !replies.include?(topics(:first))
|
141
|
+
assert_equal topics(:first), assert_no_queries { replies.first.topic }
|
142
|
+
end
|
143
|
+
|
144
|
+
unless current_adapter?(:IBM_DBAdapter)
|
145
|
+
def test_eager_association_loading_with_multiple_stis_and_order
|
146
|
+
author = Author.find(:first, :include => { :posts => [ :special_comments , :very_special_comment ] }, :order => ['authors.name', 'comments.body', 'very_special_comments_posts.body'], :conditions => 'posts.id = 4')
|
147
|
+
assert_equal authors(:david), author
|
148
|
+
assert_no_queries do
|
149
|
+
author.posts.first.special_comments
|
150
|
+
author.posts.first.very_special_comment
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_eager_association_loading_of_stis_with_multiple_references
|
156
|
+
authors = Author.find(:all, :include => { :posts => { :special_comments => { :post => [ :special_comments, :very_special_comment ] } } }, :order => 'comments.body, very_special_comments_posts.body', :conditions => 'posts.id = 4')
|
157
|
+
assert_equal [authors(:david)], authors
|
158
|
+
assert_no_queries do
|
159
|
+
authors.first.posts.first.special_comments.first.post.special_comments
|
160
|
+
authors.first.posts.first.special_comments.first.post.very_special_comment
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_eager_association_loading_where_first_level_returns_nil
|
165
|
+
authors = Author.find(:all, :include => {:post_about_thinking => :comments}, :order => 'authors.id DESC')
|
166
|
+
assert_equal [authors(:bob), authors(:mary), authors(:david)], authors
|
167
|
+
assert_no_queries do
|
168
|
+
authors[2].post_about_thinking.comments.first
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_eager_association_loading_with_recursive_cascading_four_levels_has_many_through
|
173
|
+
source = Vertex.find(:first, :include=>{:sinks=>{:sinks=>{:sinks=>:sinks}}}, :order => 'vertices.id')
|
174
|
+
assert_equal vertices(:vertex_4), assert_no_queries { source.sinks.first.sinks.first.sinks.first }
|
175
|
+
end
|
176
|
+
|
177
|
+
def test_eager_association_loading_with_recursive_cascading_four_levels_has_and_belongs_to_many
|
178
|
+
sink = Vertex.find(:first, :include=>{:sources=>{:sources=>{:sources=>:sources}}}, :order => 'vertices.id DESC')
|
179
|
+
assert_equal vertices(:vertex_1), assert_no_queries { sink.sources.first.sources.first.sources.first.sources.first }
|
180
|
+
end
|
181
|
+
end
|
@@ -1,851 +1,851 @@
|
|
1
|
-
require "cases/helper"
|
2
|
-
require 'models/developer'
|
3
|
-
require 'models/project'
|
4
|
-
require 'models/company'
|
5
|
-
require 'models/customer'
|
6
|
-
require 'models/order'
|
7
|
-
require 'models/categorization'
|
8
|
-
require 'models/category'
|
9
|
-
require 'models/post'
|
10
|
-
require 'models/author'
|
11
|
-
require 'models/tag'
|
12
|
-
require 'models/tagging'
|
13
|
-
require 'models/parrot'
|
14
|
-
require 'models/pirate'
|
15
|
-
require 'models/treasure'
|
16
|
-
require 'models/price_estimate'
|
17
|
-
require 'models/club'
|
18
|
-
require 'models/member'
|
19
|
-
require 'models/membership'
|
20
|
-
require 'models/sponsor'
|
21
|
-
require 'models/country'
|
22
|
-
require 'models/treaty'
|
23
|
-
require 'active_support/core_ext/string/conversions'
|
24
|
-
|
25
|
-
class ProjectWithAfterCreateHook < ActiveRecord::Base
|
26
|
-
self.table_name = 'projects'
|
27
|
-
has_and_belongs_to_many :developers,
|
28
|
-
:class_name => "DeveloperForProjectWithAfterCreateHook",
|
29
|
-
:join_table => "developers_projects",
|
30
|
-
:foreign_key => "project_id",
|
31
|
-
:association_foreign_key => "developer_id"
|
32
|
-
|
33
|
-
after_create :add_david
|
34
|
-
|
35
|
-
def add_david
|
36
|
-
david = DeveloperForProjectWithAfterCreateHook.find_by_name('David')
|
37
|
-
david.projects << self
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
class DeveloperForProjectWithAfterCreateHook < ActiveRecord::Base
|
42
|
-
self.table_name = 'developers'
|
43
|
-
has_and_belongs_to_many :projects,
|
44
|
-
:class_name => "ProjectWithAfterCreateHook",
|
45
|
-
:join_table => "developers_projects",
|
46
|
-
:association_foreign_key => "project_id",
|
47
|
-
:foreign_key => "developer_id"
|
48
|
-
end
|
49
|
-
|
50
|
-
class ProjectWithSymbolsForKeys < ActiveRecord::Base
|
51
|
-
self.table_name = 'projects'
|
52
|
-
has_and_belongs_to_many :developers,
|
53
|
-
:class_name => "DeveloperWithSymbolsForKeys",
|
54
|
-
:join_table => :developers_projects,
|
55
|
-
:foreign_key => :project_id,
|
56
|
-
:association_foreign_key => "developer_id"
|
57
|
-
end
|
58
|
-
|
59
|
-
class DeveloperWithSymbolsForKeys < ActiveRecord::Base
|
60
|
-
self.table_name = 'developers'
|
61
|
-
has_and_belongs_to_many :projects,
|
62
|
-
:class_name => "ProjectWithSymbolsForKeys",
|
63
|
-
:join_table => :developers_projects,
|
64
|
-
:association_foreign_key => :project_id,
|
65
|
-
:foreign_key => "developer_id"
|
66
|
-
end
|
67
|
-
|
68
|
-
class DeveloperWithCounterSQL < ActiveRecord::Base
|
69
|
-
self.table_name = 'developers'
|
70
|
-
has_and_belongs_to_many :projects,
|
71
|
-
:class_name => "DeveloperWithCounterSQL",
|
72
|
-
:join_table => "developers_projects",
|
73
|
-
:association_foreign_key => "project_id",
|
74
|
-
:foreign_key => "developer_id",
|
75
|
-
:counter_sql => proc { "SELECT COUNT(*) AS count_all FROM projects INNER JOIN developers_projects ON projects.id = developers_projects.project_id WHERE developers_projects.developer_id =#{id}" }
|
76
|
-
end
|
77
|
-
|
78
|
-
class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
79
|
-
fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects,
|
80
|
-
:parrots, :pirates, :parrots_pirates, :treasures, :price_estimates, :tags, :taggings
|
81
|
-
|
82
|
-
def setup_data_for_habtm_case
|
83
|
-
ActiveRecord::Base.connection.execute('delete from countries_treaties')
|
84
|
-
|
85
|
-
country = Country.new(:name => 'India')
|
86
|
-
country.country_id = 'c1'
|
87
|
-
country.save!
|
88
|
-
|
89
|
-
treaty = Treaty.new(:name => 'peace')
|
90
|
-
treaty.treaty_id = 't1'
|
91
|
-
country.treaties << treaty
|
92
|
-
end
|
93
|
-
|
94
|
-
def test_should_property_quote_string_primary_keys
|
95
|
-
setup_data_for_habtm_case
|
96
|
-
|
97
|
-
con = ActiveRecord::Base.connection
|
98
|
-
sql = 'select * from countries_treaties'
|
99
|
-
record = con.select_rows(sql).last
|
100
|
-
assert_equal 'c1', record[0]
|
101
|
-
assert_equal 't1', record[1]
|
102
|
-
end
|
103
|
-
|
104
|
-
def test_proper_usage_of_primary_keys_and_join_table
|
105
|
-
setup_data_for_habtm_case
|
106
|
-
|
107
|
-
assert_equal 'country_id', Country.primary_key
|
108
|
-
assert_equal 'treaty_id', Treaty.primary_key
|
109
|
-
|
110
|
-
country = Country.first
|
111
|
-
assert_equal 1, country.treaties.count
|
112
|
-
end
|
113
|
-
|
114
|
-
def test_has_and_belongs_to_many
|
115
|
-
david = Developer.find(1)
|
116
|
-
|
117
|
-
assert !david.projects.empty?
|
118
|
-
assert_equal 2, david.projects.size
|
119
|
-
|
120
|
-
active_record = Project.find(1)
|
121
|
-
assert !active_record.developers.empty?
|
122
|
-
assert_equal 3, active_record.developers.size
|
123
|
-
assert active_record.developers.include?(david)
|
124
|
-
end
|
125
|
-
|
126
|
-
def test_triple_equality
|
127
|
-
assert !(Array === Developer.find(1).projects)
|
128
|
-
assert Developer.find(1).projects === Array
|
129
|
-
end
|
130
|
-
|
131
|
-
def test_adding_single
|
132
|
-
jamis = Developer.find(2)
|
133
|
-
jamis.projects.reload # causing the collection to load
|
134
|
-
action_controller = Project.find(2)
|
135
|
-
assert_equal 1, jamis.projects.size
|
136
|
-
assert_equal 1, action_controller.developers.size
|
137
|
-
|
138
|
-
jamis.projects << action_controller
|
139
|
-
|
140
|
-
assert_equal 2, jamis.projects.size
|
141
|
-
assert_equal 2, jamis.projects(true).size
|
142
|
-
assert_equal 2, action_controller.developers(true).size
|
143
|
-
end
|
144
|
-
|
145
|
-
def test_adding_type_mismatch
|
146
|
-
jamis = Developer.find(2)
|
147
|
-
assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << nil }
|
148
|
-
assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << 1 }
|
149
|
-
end
|
150
|
-
|
151
|
-
def test_adding_from_the_project
|
152
|
-
jamis = Developer.find(2)
|
153
|
-
action_controller = Project.find(2)
|
154
|
-
action_controller.developers.reload
|
155
|
-
assert_equal 1, jamis.projects.size
|
156
|
-
assert_equal 1, action_controller.developers.size
|
157
|
-
|
158
|
-
action_controller.developers << jamis
|
159
|
-
|
160
|
-
assert_equal 2, jamis.projects(true).size
|
161
|
-
assert_equal 2, action_controller.developers.size
|
162
|
-
assert_equal 2, action_controller.developers(true).size
|
163
|
-
end
|
164
|
-
|
165
|
-
def test_adding_from_the_project_fixed_timestamp
|
166
|
-
jamis = Developer.find(2)
|
167
|
-
action_controller = Project.find(2)
|
168
|
-
action_controller.developers.reload
|
169
|
-
assert_equal 1, jamis.projects.size
|
170
|
-
assert_equal 1, action_controller.developers.size
|
171
|
-
updated_at = jamis.updated_at
|
172
|
-
|
173
|
-
action_controller.developers << jamis
|
174
|
-
|
175
|
-
assert_equal updated_at, jamis.updated_at
|
176
|
-
assert_equal 2, jamis.projects(true).size
|
177
|
-
assert_equal 2, action_controller.developers.size
|
178
|
-
assert_equal 2, action_controller.developers(true).size
|
179
|
-
end
|
180
|
-
|
181
|
-
def test_adding_multiple
|
182
|
-
aredridel = Developer.new("name" => "Aredridel")
|
183
|
-
aredridel.save
|
184
|
-
aredridel.projects.reload
|
185
|
-
aredridel.projects.push(Project.find(1), Project.find(2))
|
186
|
-
assert_equal 2, aredridel.projects.size
|
187
|
-
assert_equal 2, aredridel.projects(true).size
|
188
|
-
end
|
189
|
-
|
190
|
-
def test_adding_a_collection
|
191
|
-
aredridel = Developer.new("name" => "Aredridel")
|
192
|
-
aredridel.save
|
193
|
-
aredridel.projects.reload
|
194
|
-
aredridel.projects.concat([Project.find(1), Project.find(2)])
|
195
|
-
assert_equal 2, aredridel.projects.size
|
196
|
-
assert_equal 2, aredridel.projects(true).size
|
197
|
-
end
|
198
|
-
|
199
|
-
def test_habtm_adding_before_save
|
200
|
-
no_of_devels = Developer.count
|
201
|
-
no_of_projects = Project.count
|
202
|
-
aredridel = Developer.new("name" => "Aredridel")
|
203
|
-
aredridel.projects.concat([Project.find(1), p = Project.new("name" => "Projekt")])
|
204
|
-
assert !aredridel.persisted?
|
205
|
-
assert !p.persisted?
|
206
|
-
assert aredridel.save
|
207
|
-
assert aredridel.persisted?
|
208
|
-
assert_equal no_of_devels+1, Developer.count
|
209
|
-
assert_equal no_of_projects+1, Project.count
|
210
|
-
assert_equal 2, aredridel.projects.size
|
211
|
-
assert_equal 2, aredridel.projects(true).size
|
212
|
-
end
|
213
|
-
|
214
|
-
def test_habtm_saving_multiple_relationships
|
215
|
-
new_project = Project.new("name" => "Grimetime")
|
216
|
-
amount_of_developers = 4
|
217
|
-
developers = (0...amount_of_developers).collect {|i| Developer.create(:name => "JME #{i}") }.reverse
|
218
|
-
|
219
|
-
new_project.developer_ids = [developers[0].id, developers[1].id]
|
220
|
-
new_project.developers_with_callback_ids = [developers[2].id, developers[3].id]
|
221
|
-
assert new_project.save
|
222
|
-
|
223
|
-
new_project.reload
|
224
|
-
assert_equal amount_of_developers, new_project.developers.size
|
225
|
-
assert_equal developers, new_project.developers
|
226
|
-
end
|
227
|
-
|
228
|
-
def test_habtm_unique_order_preserved
|
229
|
-
assert_equal developers(:poor_jamis, :jamis, :david), projects(:active_record).non_unique_developers
|
230
|
-
assert_equal developers(:poor_jamis, :jamis, :david), projects(:active_record).developers
|
231
|
-
end
|
232
|
-
|
233
|
-
def test_build
|
234
|
-
devel = Developer.find(1)
|
235
|
-
proj = assert_no_queries { devel.projects.build("name" => "Projekt") }
|
236
|
-
assert !devel.projects.loaded?
|
237
|
-
|
238
|
-
assert_equal devel.projects.last, proj
|
239
|
-
assert devel.projects.loaded?
|
240
|
-
|
241
|
-
assert !proj.persisted?
|
242
|
-
devel.save
|
243
|
-
assert proj.persisted?
|
244
|
-
assert_equal devel.projects.last, proj
|
245
|
-
assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
|
246
|
-
end
|
247
|
-
|
248
|
-
def test_new_aliased_to_build
|
249
|
-
devel = Developer.find(1)
|
250
|
-
proj = assert_no_queries { devel.projects.new("name" => "Projekt") }
|
251
|
-
assert !devel.projects.loaded?
|
252
|
-
|
253
|
-
assert_equal devel.projects.last, proj
|
254
|
-
assert devel.projects.loaded?
|
255
|
-
|
256
|
-
assert !proj.persisted?
|
257
|
-
devel.save
|
258
|
-
assert proj.persisted?
|
259
|
-
assert_equal devel.projects.last, proj
|
260
|
-
assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
|
261
|
-
end
|
262
|
-
|
263
|
-
def test_build_by_new_record
|
264
|
-
devel = Developer.new(:name => "Marcel", :salary => 75000)
|
265
|
-
devel.projects.build(:name => "Make bed")
|
266
|
-
proj2 = devel.projects.build(:name => "Lie in it")
|
267
|
-
assert_equal devel.projects.last, proj2
|
268
|
-
assert !proj2.persisted?
|
269
|
-
devel.save
|
270
|
-
assert devel.persisted?
|
271
|
-
assert proj2.persisted?
|
272
|
-
assert_equal devel.projects.last, proj2
|
273
|
-
assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
|
274
|
-
end
|
275
|
-
|
276
|
-
def test_create
|
277
|
-
devel = Developer.find(1)
|
278
|
-
proj = devel.projects.create("name" => "Projekt")
|
279
|
-
assert !devel.projects.loaded?
|
280
|
-
|
281
|
-
assert_equal devel.projects.last, proj
|
282
|
-
assert !devel.projects.loaded?
|
283
|
-
|
284
|
-
assert proj.persisted?
|
285
|
-
assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
|
286
|
-
end
|
287
|
-
|
288
|
-
def test_create_by_new_record
|
289
|
-
devel = Developer.new(:name => "Marcel", :salary => 75000)
|
290
|
-
devel.projects.build(:name => "Make bed")
|
291
|
-
proj2 = devel.projects.build(:name => "Lie in it")
|
292
|
-
assert_equal devel.projects.last, proj2
|
293
|
-
assert !proj2.persisted?
|
294
|
-
devel.save
|
295
|
-
assert devel.persisted?
|
296
|
-
assert proj2.persisted?
|
297
|
-
assert_equal devel.projects.last, proj2
|
298
|
-
assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
|
299
|
-
end
|
300
|
-
|
301
|
-
def test_creation_respects_hash_condition
|
302
|
-
# in Oracle '' is saved as null therefore need to save ' ' in not null column
|
303
|
-
post = categories(:general).post_with_conditions.build(:body => ' ')
|
304
|
-
|
305
|
-
assert post.save
|
306
|
-
assert_equal 'Yet Another Testing Title', post.title
|
307
|
-
|
308
|
-
# in Oracle '' is saved as null therefore need to save ' ' in not null column
|
309
|
-
another_post = categories(:general).post_with_conditions.create(:body => ' ')
|
310
|
-
|
311
|
-
assert another_post.persisted?
|
312
|
-
assert_equal 'Yet Another Testing Title', another_post.title
|
313
|
-
end
|
314
|
-
|
315
|
-
def test_uniq_after_the_fact
|
316
|
-
dev = developers(:jamis)
|
317
|
-
dev.projects << projects(:active_record)
|
318
|
-
dev.projects << projects(:active_record)
|
319
|
-
|
320
|
-
assert_equal 3, dev.projects.size
|
321
|
-
assert_equal 1, dev.projects.uniq.size
|
322
|
-
end
|
323
|
-
|
324
|
-
def test_uniq_before_the_fact
|
325
|
-
projects(:active_record).developers << developers(:jamis)
|
326
|
-
projects(:active_record).developers << developers(:david)
|
327
|
-
assert_equal 3, projects(:active_record, :reload).developers.size
|
328
|
-
end
|
329
|
-
|
330
|
-
def test_uniq_option_prevents_duplicate_push
|
331
|
-
project = projects(:active_record)
|
332
|
-
project.developers << developers(:jamis)
|
333
|
-
project.developers << developers(:david)
|
334
|
-
assert_equal 3, project.developers.size
|
335
|
-
|
336
|
-
project.developers << developers(:david)
|
337
|
-
project.developers << developers(:jamis)
|
338
|
-
assert_equal 3, project.developers.size
|
339
|
-
end
|
340
|
-
|
341
|
-
def test_deleting
|
342
|
-
david = Developer.find(1)
|
343
|
-
active_record = Project.find(1)
|
344
|
-
david.projects.reload
|
345
|
-
assert_equal 2, david.projects.size
|
346
|
-
assert_equal 3, active_record.developers.size
|
347
|
-
|
348
|
-
david.projects.delete(active_record)
|
349
|
-
|
350
|
-
assert_equal 1, david.projects.size
|
351
|
-
assert_equal 1, david.projects(true).size
|
352
|
-
assert_equal 2, active_record.developers(true).size
|
353
|
-
end
|
354
|
-
|
355
|
-
def test_deleting_array
|
356
|
-
david = Developer.find(1)
|
357
|
-
david.projects.reload
|
358
|
-
david.projects.delete(Project.find(:all))
|
359
|
-
assert_equal 0, david.projects.size
|
360
|
-
assert_equal 0, david.projects(true).size
|
361
|
-
end
|
362
|
-
|
363
|
-
def test_deleting_with_sql
|
364
|
-
david = Developer.find(1)
|
365
|
-
active_record = Project.find(1)
|
366
|
-
active_record.developers.reload
|
367
|
-
assert_equal 3, active_record.developers_by_sql.size
|
368
|
-
|
369
|
-
active_record.developers_by_sql.delete(david)
|
370
|
-
assert_equal 2, active_record.developers_by_sql(true).size
|
371
|
-
end
|
372
|
-
|
373
|
-
def test_deleting_array_with_sql
|
374
|
-
active_record = Project.find(1)
|
375
|
-
active_record.developers.reload
|
376
|
-
assert_equal 3, active_record.developers_by_sql.size
|
377
|
-
|
378
|
-
active_record.developers_by_sql.delete(Developer.find(:all))
|
379
|
-
assert_equal 0, active_record.developers_by_sql(true).size
|
380
|
-
end
|
381
|
-
|
382
|
-
def test_deleting_all
|
383
|
-
david = Developer.find(1)
|
384
|
-
david.projects.reload
|
385
|
-
david.projects.clear
|
386
|
-
assert_equal 0, david.projects.size
|
387
|
-
assert_equal 0, david.projects(true).size
|
388
|
-
end
|
389
|
-
|
390
|
-
def test_removing_associations_on_destroy
|
391
|
-
david = DeveloperWithBeforeDestroyRaise.find(1)
|
392
|
-
assert !david.projects.empty?
|
393
|
-
david.destroy
|
394
|
-
assert david.projects.empty?
|
395
|
-
assert DeveloperWithBeforeDestroyRaise.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = 1").empty?
|
396
|
-
end
|
397
|
-
|
398
|
-
def test_destroying
|
399
|
-
david = Developer.find(1)
|
400
|
-
project = Project.find(1)
|
401
|
-
david.projects.reload
|
402
|
-
assert_equal 2, david.projects.size
|
403
|
-
assert_equal 3, project.developers.size
|
404
|
-
|
405
|
-
assert_no_difference "Project.count" do
|
406
|
-
david.projects.destroy(project)
|
407
|
-
end
|
408
|
-
|
409
|
-
join_records = Developer.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = #{david.id} AND project_id = #{project.id}")
|
410
|
-
assert join_records.empty?
|
411
|
-
|
412
|
-
assert_equal 1, david.reload.projects.size
|
413
|
-
assert_equal 1, david.projects(true).size
|
414
|
-
end
|
415
|
-
|
416
|
-
def test_destroying_many
|
417
|
-
david = Developer.find(1)
|
418
|
-
david.projects.reload
|
419
|
-
projects = Project.all
|
420
|
-
|
421
|
-
assert_no_difference "Project.count" do
|
422
|
-
david.projects.destroy(*projects)
|
423
|
-
end
|
424
|
-
|
425
|
-
join_records = Developer.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = #{david.id}")
|
426
|
-
assert join_records.empty?
|
427
|
-
|
428
|
-
assert_equal 0, david.reload.projects.size
|
429
|
-
assert_equal 0, david.projects(true).size
|
430
|
-
end
|
431
|
-
|
432
|
-
def test_destroy_all
|
433
|
-
david = Developer.find(1)
|
434
|
-
david.projects.reload
|
435
|
-
assert !david.projects.empty?
|
436
|
-
|
437
|
-
assert_no_difference "Project.count" do
|
438
|
-
david.projects.destroy_all
|
439
|
-
end
|
440
|
-
|
441
|
-
join_records = Developer.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = #{david.id}")
|
442
|
-
assert join_records.empty?
|
443
|
-
|
444
|
-
assert david.projects.empty?
|
445
|
-
assert david.projects(true).empty?
|
446
|
-
end
|
447
|
-
|
448
|
-
def test_destroy_associations_destroys_multiple_associations
|
449
|
-
george = parrots(:george)
|
450
|
-
assert !george.pirates.empty?
|
451
|
-
assert !george.treasures.empty?
|
452
|
-
|
453
|
-
assert_no_difference "Pirate.count" do
|
454
|
-
assert_no_difference "Treasure.count" do
|
455
|
-
george.destroy_associations
|
456
|
-
end
|
457
|
-
end
|
458
|
-
|
459
|
-
join_records = Parrot.connection.select_all("SELECT * FROM parrots_pirates WHERE parrot_id = #{george.id}")
|
460
|
-
assert join_records.empty?
|
461
|
-
assert george.pirates(true).empty?
|
462
|
-
|
463
|
-
join_records = Parrot.connection.select_all("SELECT * FROM parrots_treasures WHERE parrot_id = #{george.id}")
|
464
|
-
assert join_records.empty?
|
465
|
-
assert george.treasures(true).empty?
|
466
|
-
end
|
467
|
-
|
468
|
-
def test_deprecated_push_with_attributes_was_removed
|
469
|
-
jamis = developers(:jamis)
|
470
|
-
assert_raise(NoMethodError) do
|
471
|
-
jamis.projects.push_with_attributes(projects(:action_controller), :joined_on => Date.today)
|
472
|
-
end
|
473
|
-
end
|
474
|
-
|
475
|
-
def test_associations_with_conditions
|
476
|
-
assert_equal 3, projects(:active_record).developers.size
|
477
|
-
assert_equal 1, projects(:active_record).developers_named_david.size
|
478
|
-
assert_equal 1, projects(:active_record).developers_named_david_with_hash_conditions.size
|
479
|
-
|
480
|
-
assert_equal developers(:david), projects(:active_record).developers_named_david.find(developers(:david).id)
|
481
|
-
assert_equal developers(:david), projects(:active_record).developers_named_david_with_hash_conditions.find(developers(:david).id)
|
482
|
-
assert_equal developers(:david), projects(:active_record).salaried_developers.find(developers(:david).id)
|
483
|
-
|
484
|
-
projects(:active_record).developers_named_david.clear
|
485
|
-
assert_equal 2, projects(:active_record, :reload).developers.size
|
486
|
-
end
|
487
|
-
|
488
|
-
def test_find_in_association
|
489
|
-
# Using sql
|
490
|
-
assert_equal developers(:david), projects(:active_record).developers.find(developers(:david).id), "SQL find"
|
491
|
-
|
492
|
-
# Using ruby
|
493
|
-
active_record = projects(:active_record)
|
494
|
-
active_record.developers.reload
|
495
|
-
assert_equal developers(:david), active_record.developers.find(developers(:david).id), "Ruby find"
|
496
|
-
end
|
497
|
-
|
498
|
-
def test_include_uses_array_include_after_loaded
|
499
|
-
project = projects(:active_record)
|
500
|
-
project.developers.class # force load target
|
501
|
-
|
502
|
-
developer = project.developers.first
|
503
|
-
|
504
|
-
assert_no_queries do
|
505
|
-
assert project.developers.loaded?
|
506
|
-
assert project.developers.include?(developer)
|
507
|
-
end
|
508
|
-
end
|
509
|
-
|
510
|
-
def test_include_checks_if_record_exists_if_target_not_loaded
|
511
|
-
project = projects(:active_record)
|
512
|
-
developer = project.developers.first
|
513
|
-
|
514
|
-
project.reload
|
515
|
-
assert ! project.developers.loaded?
|
516
|
-
assert_queries(1) do
|
517
|
-
assert project.developers.include?(developer)
|
518
|
-
end
|
519
|
-
assert ! project.developers.loaded?
|
520
|
-
end
|
521
|
-
|
522
|
-
def test_include_returns_false_for_non_matching_record_to_verify_scoping
|
523
|
-
project = projects(:active_record)
|
524
|
-
developer = Developer.create :name => "Bryan", :salary => 50_000
|
525
|
-
|
526
|
-
assert ! project.developers.loaded?
|
527
|
-
assert ! project.developers.include?(developer)
|
528
|
-
end
|
529
|
-
|
530
|
-
def test_find_in_association_with_custom_finder_sql
|
531
|
-
assert_equal developers(:david), projects(:active_record).developers_with_finder_sql.find(developers(:david).id), "SQL find"
|
532
|
-
|
533
|
-
active_record = projects(:active_record)
|
534
|
-
active_record.developers_with_finder_sql.reload
|
535
|
-
assert_equal developers(:david), active_record.developers_with_finder_sql.find(developers(:david).id), "Ruby find"
|
536
|
-
end
|
537
|
-
|
538
|
-
def test_find_in_association_with_custom_finder_sql_and_multiple_interpolations
|
539
|
-
# interpolate once:
|
540
|
-
assert_equal [developers(:david), developers(:jamis), developers(:poor_jamis)], projects(:active_record).developers_with_finder_sql, "first interpolation"
|
541
|
-
# interpolate again, for a different project id
|
542
|
-
assert_equal [developers(:david)], projects(:action_controller).developers_with_finder_sql, "second interpolation"
|
543
|
-
end
|
544
|
-
|
545
|
-
def test_find_in_association_with_custom_finder_sql_and_string_id
|
546
|
-
assert_equal developers(:david), projects(:active_record).developers_with_finder_sql.find(developers(:david).id.to_s), "SQL find"
|
547
|
-
end
|
548
|
-
|
549
|
-
def test_find_with_merged_options
|
550
|
-
assert_equal 1, projects(:active_record).limited_developers.size
|
551
|
-
assert_equal 1, projects(:active_record).limited_developers.find(:all).size
|
552
|
-
assert_equal 3, projects(:active_record).limited_developers.find(:all, :limit => nil).size
|
553
|
-
end
|
554
|
-
|
555
|
-
def test_dynamic_find_should_respect_association_order
|
556
|
-
# Developers are ordered 'name DESC, id DESC'
|
557
|
-
high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
|
558
|
-
|
559
|
-
assert_equal high_id_jamis, projects(:active_record).developers.find(:first, :conditions => "name = 'Jamis'")
|
560
|
-
assert_equal high_id_jamis, projects(:active_record).developers.find_by_name('Jamis')
|
561
|
-
end
|
562
|
-
|
563
|
-
def test_dynamic_find_all_should_respect_association_order
|
564
|
-
# Developers are ordered 'name DESC, id DESC'
|
565
|
-
low_id_jamis = developers(:jamis)
|
566
|
-
middle_id_jamis = developers(:poor_jamis)
|
567
|
-
high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
|
568
|
-
|
569
|
-
assert_equal [high_id_jamis, middle_id_jamis, low_id_jamis], projects(:active_record).developers.find(:all, :conditions => "name = 'Jamis'")
|
570
|
-
assert_equal [high_id_jamis, middle_id_jamis, low_id_jamis], projects(:active_record).developers.find_all_by_name('Jamis')
|
571
|
-
end
|
572
|
-
|
573
|
-
def test_find_should_append_to_association_order
|
574
|
-
ordered_developers = projects(:active_record).developers.order('projects.id')
|
575
|
-
assert_equal ['developers.name desc, developers.id desc', 'projects.id'], ordered_developers.order_values
|
576
|
-
end
|
577
|
-
|
578
|
-
def test_dynamic_find_all_should_respect_association_limit
|
579
|
-
assert_equal 1, projects(:active_record).limited_developers.find(:all, :conditions => "name = 'Jamis'").length
|
580
|
-
assert_equal 1, projects(:active_record).limited_developers.find_all_by_name('Jamis').length
|
581
|
-
end
|
582
|
-
|
583
|
-
def test_dynamic_find_all_order_should_override_association_limit
|
584
|
-
assert_equal 2, projects(:active_record).limited_developers.find(:all, :conditions => "name = 'Jamis'", :limit => 9_000).length
|
585
|
-
assert_equal 2, projects(:active_record).limited_developers.find_all_by_name('Jamis', :limit => 9_000).length
|
586
|
-
end
|
587
|
-
|
588
|
-
def test_dynamic_find_all_should_respect_readonly_access
|
589
|
-
projects(:active_record).readonly_developers.each { |d| assert_raise(ActiveRecord::ReadOnlyRecord) { d.save! } if d.valid?}
|
590
|
-
projects(:active_record).readonly_developers.each { |d| d.readonly? }
|
591
|
-
end
|
592
|
-
|
593
|
-
def test_new_with_values_in_collection
|
594
|
-
jamis = DeveloperForProjectWithAfterCreateHook.find_by_name('Jamis')
|
595
|
-
david = DeveloperForProjectWithAfterCreateHook.find_by_name('David')
|
596
|
-
project = ProjectWithAfterCreateHook.new(:name => "Cooking with Bertie")
|
597
|
-
project.developers << jamis
|
598
|
-
project.save!
|
599
|
-
project.reload
|
600
|
-
|
601
|
-
assert project.developers.include?(jamis)
|
602
|
-
assert project.developers.include?(david)
|
603
|
-
end
|
604
|
-
|
605
|
-
def test_find_in_association_with_options
|
606
|
-
developers = projects(:active_record).developers.all
|
607
|
-
assert_equal 3, developers.size
|
608
|
-
|
609
|
-
assert_equal developers(:poor_jamis), projects(:active_record).developers.where("salary < 10000").first
|
610
|
-
end
|
611
|
-
|
612
|
-
def test_replace_with_less
|
613
|
-
david = developers(:david)
|
614
|
-
david.projects = [projects(:action_controller)]
|
615
|
-
assert david.save
|
616
|
-
assert_equal 1, david.projects.length
|
617
|
-
end
|
618
|
-
|
619
|
-
def test_replace_with_new
|
620
|
-
david = developers(:david)
|
621
|
-
david.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")]
|
622
|
-
david.save
|
623
|
-
assert_equal 2, david.projects.length
|
624
|
-
assert !david.projects.include?(projects(:active_record))
|
625
|
-
end
|
626
|
-
|
627
|
-
def test_replace_on_new_object
|
628
|
-
new_developer = Developer.new("name" => "Matz")
|
629
|
-
new_developer.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")]
|
630
|
-
new_developer.save
|
631
|
-
assert_equal 2, new_developer.projects.length
|
632
|
-
end
|
633
|
-
|
634
|
-
def test_consider_type
|
635
|
-
developer = Developer.find(:first)
|
636
|
-
special_project = SpecialProject.create("name" => "Special Project")
|
637
|
-
|
638
|
-
other_project = developer.projects.first
|
639
|
-
developer.special_projects << special_project
|
640
|
-
developer.reload
|
641
|
-
|
642
|
-
assert developer.projects.include?(special_project)
|
643
|
-
assert developer.special_projects.include?(special_project)
|
644
|
-
assert !developer.special_projects.include?(other_project)
|
645
|
-
end
|
646
|
-
|
647
|
-
def test_update_attributes_after_push_without_duplicate_join_table_rows
|
648
|
-
developer = Developer.new("name" => "Kano")
|
649
|
-
project = SpecialProject.create("name" => "Special Project")
|
650
|
-
assert developer.save
|
651
|
-
developer.projects << project
|
652
|
-
developer.update_column("name", "Bruza")
|
653
|
-
assert_equal 1, Developer.connection.select_value(<<-end_sql).to_i
|
654
|
-
SELECT count(*) FROM developers_projects
|
655
|
-
WHERE project_id = #{project.id}
|
656
|
-
AND developer_id = #{developer.id}
|
657
|
-
end_sql
|
658
|
-
end
|
659
|
-
|
660
|
-
def test_updating_attributes_on_non_rich_associations
|
661
|
-
welcome = categories(:technology).posts.first
|
662
|
-
welcome.title = "Something else"
|
663
|
-
assert welcome.save!
|
664
|
-
end
|
665
|
-
|
666
|
-
def test_habtm_respects_select
|
667
|
-
categories(:technology).select_testing_posts(true).each do |o|
|
668
|
-
assert_respond_to o, :correctness_marker
|
669
|
-
end
|
670
|
-
assert_respond_to categories(:technology).select_testing_posts.find(:first), :correctness_marker
|
671
|
-
end
|
672
|
-
|
673
|
-
def test_habtm_selects_all_columns_by_default
|
674
|
-
assert_equal Project.column_names.sort, developers(:david).projects.first.attributes.keys.sort
|
675
|
-
end
|
676
|
-
|
677
|
-
def test_habtm_respects_select_query_method
|
678
|
-
assert_equal ['id'], developers(:david).projects.select(:id).first.attributes.keys
|
679
|
-
end
|
680
|
-
|
681
|
-
def test_join_table_alias
|
682
|
-
assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL').size
|
683
|
-
end
|
684
|
-
|
685
|
-
def test_join_with_group
|
686
|
-
group = Developer.columns.inject([]) do |g, c|
|
687
|
-
g << "developers.#{c.name}"
|
688
|
-
g << "developers_projects_2.#{c.name}"
|
689
|
-
end
|
690
|
-
Project.columns.each { |c| group << "projects.#{c.name}" }
|
691
|
-
|
692
|
-
assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL', :group => group.join(",")).size
|
693
|
-
end
|
694
|
-
|
695
|
-
def test_find_grouped
|
696
|
-
all_posts_from_category1 = Post.find(:all, :conditions => "category_id = 1", :joins => :categories)
|
697
|
-
grouped_posts_of_category1 = Post.find(:all, :conditions => "category_id = 1", :group => "author_id", :select => 'count(posts.id) as posts_count', :joins => :categories)
|
698
|
-
assert_equal 5, all_posts_from_category1.size
|
699
|
-
assert_equal 2, grouped_posts_of_category1.size
|
700
|
-
end
|
701
|
-
|
702
|
-
def test_find_scoped_grouped
|
703
|
-
assert_equal 5, categories(:general).posts_grouped_by_title.size
|
704
|
-
assert_equal 1, categories(:technology).posts_grouped_by_title.size
|
705
|
-
end
|
706
|
-
|
707
|
-
def test_find_scoped_grouped_having
|
708
|
-
assert_equal 2, projects(:active_record).well_payed_salary_groups.size
|
709
|
-
assert projects(:active_record).well_payed_salary_groups.all? { |g| g.salary > 10000 }
|
710
|
-
end
|
711
|
-
|
712
|
-
def test_get_ids
|
713
|
-
assert_equal projects(:active_record, :action_controller).map(&:id).sort, developers(:david).project_ids.sort
|
714
|
-
assert_equal [projects(:active_record).id], developers(:jamis).project_ids
|
715
|
-
end
|
716
|
-
|
717
|
-
def test_get_ids_for_loaded_associations
|
718
|
-
developer = developers(:david)
|
719
|
-
developer.projects(true)
|
720
|
-
assert_queries(0) do
|
721
|
-
developer.project_ids
|
722
|
-
developer.project_ids
|
723
|
-
end
|
724
|
-
end
|
725
|
-
|
726
|
-
def test_get_ids_for_unloaded_associations_does_not_load_them
|
727
|
-
developer = developers(:david)
|
728
|
-
assert !developer.projects.loaded?
|
729
|
-
assert_equal projects(:active_record, :action_controller).map(&:id).sort, developer.project_ids.sort
|
730
|
-
assert !developer.projects.loaded?
|
731
|
-
end
|
732
|
-
|
733
|
-
def test_assign_ids
|
734
|
-
developer = Developer.new("name" => "Joe")
|
735
|
-
developer.project_ids = projects(:active_record, :action_controller).map(&:id)
|
736
|
-
developer.save
|
737
|
-
developer.reload
|
738
|
-
assert_equal 2, developer.projects.length
|
739
|
-
assert_equal [projects(:active_record), projects(:action_controller)].map(&:id).sort, developer.project_ids.sort
|
740
|
-
end
|
741
|
-
|
742
|
-
def test_assign_ids_ignoring_blanks
|
743
|
-
developer = Developer.new("name" => "Joe")
|
744
|
-
developer.project_ids = [projects(:active_record).id, nil, projects(:action_controller).id, '']
|
745
|
-
developer.save
|
746
|
-
developer.reload
|
747
|
-
assert_equal 2, developer.projects.length
|
748
|
-
assert_equal [projects(:active_record), projects(:action_controller)].map(&:id).sort, developer.project_ids.sort
|
749
|
-
end
|
750
|
-
|
751
|
-
def test_scoped_find_on_through_association_doesnt_return_read_only_records
|
752
|
-
tag = Post.find(1).tags.find_by_name("General")
|
753
|
-
|
754
|
-
assert_nothing_raised do
|
755
|
-
tag.save!
|
756
|
-
end
|
757
|
-
end
|
758
|
-
|
759
|
-
def test_has_many_through_polymorphic_has_manys_works
|
760
|
-
assert_equal [10, 20].to_set, pirates(:redbeard).treasure_estimates.map(&:price).to_set
|
761
|
-
end
|
762
|
-
|
763
|
-
def test_symbols_as_keys
|
764
|
-
developer = DeveloperWithSymbolsForKeys.new(:name => 'David')
|
765
|
-
project = ProjectWithSymbolsForKeys.new(:name => 'Rails Testing')
|
766
|
-
project.developers << developer
|
767
|
-
project.save!
|
768
|
-
|
769
|
-
assert_equal 1, project.developers.size
|
770
|
-
assert_equal 1, developer.projects.size
|
771
|
-
assert_equal developer, project.developers.find(:first)
|
772
|
-
assert_equal project, developer.projects.find(:first)
|
773
|
-
end
|
774
|
-
|
775
|
-
def test_self_referential_habtm_without_foreign_key_set_should_raise_exception
|
776
|
-
assert_raise(ActiveRecord::HasAndBelongsToManyAssociationForeignKeyNeeded) {
|
777
|
-
Member.class_eval do
|
778
|
-
has_and_belongs_to_many :friends, :class_name => "Member", :join_table => "member_friends"
|
779
|
-
end
|
780
|
-
}
|
781
|
-
end
|
782
|
-
|
783
|
-
def test_dynamic_find_should_respect_association_include
|
784
|
-
# SQL error in sort clause if :include is not included
|
785
|
-
# due to Unknown column 'authors.id'
|
786
|
-
assert Category.find(1).posts_with_authors_sorted_by_author_id.find_by_title('Welcome to the weblog')
|
787
|
-
end
|
788
|
-
|
789
|
-
def test_counting_on_habtm_association_and_not_array
|
790
|
-
david = Developer.find(1)
|
791
|
-
# Extra parameter just to make sure we aren't falling back to
|
792
|
-
# Array#count in Ruby >=1.8.7, which would raise an ArgumentError
|
793
|
-
assert_nothing_raised { david.projects.count(:all, :conditions => '1=1') }
|
794
|
-
end
|
795
|
-
|
796
|
-
def test_count
|
797
|
-
david = Developer.find(1)
|
798
|
-
assert_equal 2, david.projects.count
|
799
|
-
end
|
800
|
-
|
801
|
-
def test_count_with_counter_sql
|
802
|
-
developer = DeveloperWithCounterSQL.create(:name => 'tekin')
|
803
|
-
developer.project_ids = [projects(:active_record).id]
|
804
|
-
developer.save
|
805
|
-
developer.reload
|
806
|
-
assert_equal 1, developer.projects.count
|
807
|
-
end
|
808
|
-
|
809
|
-
unless current_adapter?(:PostgreSQLAdapter, :IBM_DBAdapter)
|
810
|
-
def test_count_with_finder_sql
|
811
|
-
assert_equal 3, projects(:active_record).developers_with_finder_sql.count
|
812
|
-
assert_equal 3, projects(:active_record).developers_with_multiline_finder_sql.count
|
813
|
-
end
|
814
|
-
end
|
815
|
-
|
816
|
-
def test_association_proxy_transaction_method_starts_transaction_in_association_class
|
817
|
-
Post.expects(:transaction)
|
818
|
-
Category.find(:first).posts.transaction do
|
819
|
-
# nothing
|
820
|
-
end
|
821
|
-
end
|
822
|
-
|
823
|
-
def test_caching_of_columns
|
824
|
-
david = Developer.find(1)
|
825
|
-
# clear cache possibly created by other tests
|
826
|
-
david.projects.reset_column_information
|
827
|
-
|
828
|
-
assert_queries(1) { david.projects.columns; david.projects.columns }
|
829
|
-
|
830
|
-
## and again to verify that reset_column_information clears the cache correctly
|
831
|
-
david.projects.reset_column_information
|
832
|
-
assert_queries(1) { david.projects.columns; david.projects.columns }
|
833
|
-
end
|
834
|
-
|
835
|
-
def test_attributes_are_being_set_when_initialized_from_habm_association_with_where_clause
|
836
|
-
new_developer = projects(:action_controller).developers.where(:name => "Marcelo").build
|
837
|
-
assert_equal new_developer.name, "Marcelo"
|
838
|
-
end
|
839
|
-
|
840
|
-
def test_attributes_are_being_set_when_initialized_from_habm_association_with_multiple_where_clauses
|
841
|
-
new_developer = projects(:action_controller).developers.where(:name => "Marcelo").where(:salary => 90_000).build
|
842
|
-
assert_equal new_developer.name, "Marcelo"
|
843
|
-
assert_equal new_developer.salary, 90_000
|
844
|
-
end
|
845
|
-
|
846
|
-
def test_include_method_in_has_and_belongs_to_many_association_should_return_true_for_instance_added_with_build
|
847
|
-
project = Project.new
|
848
|
-
developer = project.developers.build
|
849
|
-
assert project.developers.include?(developer)
|
850
|
-
end
|
851
|
-
end
|
1
|
+
require "cases/helper"
|
2
|
+
require 'models/developer'
|
3
|
+
require 'models/project'
|
4
|
+
require 'models/company'
|
5
|
+
require 'models/customer'
|
6
|
+
require 'models/order'
|
7
|
+
require 'models/categorization'
|
8
|
+
require 'models/category'
|
9
|
+
require 'models/post'
|
10
|
+
require 'models/author'
|
11
|
+
require 'models/tag'
|
12
|
+
require 'models/tagging'
|
13
|
+
require 'models/parrot'
|
14
|
+
require 'models/pirate'
|
15
|
+
require 'models/treasure'
|
16
|
+
require 'models/price_estimate'
|
17
|
+
require 'models/club'
|
18
|
+
require 'models/member'
|
19
|
+
require 'models/membership'
|
20
|
+
require 'models/sponsor'
|
21
|
+
require 'models/country'
|
22
|
+
require 'models/treaty'
|
23
|
+
require 'active_support/core_ext/string/conversions'
|
24
|
+
|
25
|
+
class ProjectWithAfterCreateHook < ActiveRecord::Base
|
26
|
+
self.table_name = 'projects'
|
27
|
+
has_and_belongs_to_many :developers,
|
28
|
+
:class_name => "DeveloperForProjectWithAfterCreateHook",
|
29
|
+
:join_table => "developers_projects",
|
30
|
+
:foreign_key => "project_id",
|
31
|
+
:association_foreign_key => "developer_id"
|
32
|
+
|
33
|
+
after_create :add_david
|
34
|
+
|
35
|
+
def add_david
|
36
|
+
david = DeveloperForProjectWithAfterCreateHook.find_by_name('David')
|
37
|
+
david.projects << self
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class DeveloperForProjectWithAfterCreateHook < ActiveRecord::Base
|
42
|
+
self.table_name = 'developers'
|
43
|
+
has_and_belongs_to_many :projects,
|
44
|
+
:class_name => "ProjectWithAfterCreateHook",
|
45
|
+
:join_table => "developers_projects",
|
46
|
+
:association_foreign_key => "project_id",
|
47
|
+
:foreign_key => "developer_id"
|
48
|
+
end
|
49
|
+
|
50
|
+
class ProjectWithSymbolsForKeys < ActiveRecord::Base
|
51
|
+
self.table_name = 'projects'
|
52
|
+
has_and_belongs_to_many :developers,
|
53
|
+
:class_name => "DeveloperWithSymbolsForKeys",
|
54
|
+
:join_table => :developers_projects,
|
55
|
+
:foreign_key => :project_id,
|
56
|
+
:association_foreign_key => "developer_id"
|
57
|
+
end
|
58
|
+
|
59
|
+
class DeveloperWithSymbolsForKeys < ActiveRecord::Base
|
60
|
+
self.table_name = 'developers'
|
61
|
+
has_and_belongs_to_many :projects,
|
62
|
+
:class_name => "ProjectWithSymbolsForKeys",
|
63
|
+
:join_table => :developers_projects,
|
64
|
+
:association_foreign_key => :project_id,
|
65
|
+
:foreign_key => "developer_id"
|
66
|
+
end
|
67
|
+
|
68
|
+
class DeveloperWithCounterSQL < ActiveRecord::Base
|
69
|
+
self.table_name = 'developers'
|
70
|
+
has_and_belongs_to_many :projects,
|
71
|
+
:class_name => "DeveloperWithCounterSQL",
|
72
|
+
:join_table => "developers_projects",
|
73
|
+
:association_foreign_key => "project_id",
|
74
|
+
:foreign_key => "developer_id",
|
75
|
+
:counter_sql => proc { "SELECT COUNT(*) AS count_all FROM projects INNER JOIN developers_projects ON projects.id = developers_projects.project_id WHERE developers_projects.developer_id =#{id}" }
|
76
|
+
end
|
77
|
+
|
78
|
+
class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
79
|
+
fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects,
|
80
|
+
:parrots, :pirates, :parrots_pirates, :treasures, :price_estimates, :tags, :taggings
|
81
|
+
|
82
|
+
def setup_data_for_habtm_case
|
83
|
+
ActiveRecord::Base.connection.execute('delete from countries_treaties')
|
84
|
+
|
85
|
+
country = Country.new(:name => 'India')
|
86
|
+
country.country_id = 'c1'
|
87
|
+
country.save!
|
88
|
+
|
89
|
+
treaty = Treaty.new(:name => 'peace')
|
90
|
+
treaty.treaty_id = 't1'
|
91
|
+
country.treaties << treaty
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_should_property_quote_string_primary_keys
|
95
|
+
setup_data_for_habtm_case
|
96
|
+
|
97
|
+
con = ActiveRecord::Base.connection
|
98
|
+
sql = 'select * from countries_treaties'
|
99
|
+
record = con.select_rows(sql).last
|
100
|
+
assert_equal 'c1', record[0]
|
101
|
+
assert_equal 't1', record[1]
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_proper_usage_of_primary_keys_and_join_table
|
105
|
+
setup_data_for_habtm_case
|
106
|
+
|
107
|
+
assert_equal 'country_id', Country.primary_key
|
108
|
+
assert_equal 'treaty_id', Treaty.primary_key
|
109
|
+
|
110
|
+
country = Country.first
|
111
|
+
assert_equal 1, country.treaties.count
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_has_and_belongs_to_many
|
115
|
+
david = Developer.find(1)
|
116
|
+
|
117
|
+
assert !david.projects.empty?
|
118
|
+
assert_equal 2, david.projects.size
|
119
|
+
|
120
|
+
active_record = Project.find(1)
|
121
|
+
assert !active_record.developers.empty?
|
122
|
+
assert_equal 3, active_record.developers.size
|
123
|
+
assert active_record.developers.include?(david)
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_triple_equality
|
127
|
+
assert !(Array === Developer.find(1).projects)
|
128
|
+
assert Developer.find(1).projects === Array
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_adding_single
|
132
|
+
jamis = Developer.find(2)
|
133
|
+
jamis.projects.reload # causing the collection to load
|
134
|
+
action_controller = Project.find(2)
|
135
|
+
assert_equal 1, jamis.projects.size
|
136
|
+
assert_equal 1, action_controller.developers.size
|
137
|
+
|
138
|
+
jamis.projects << action_controller
|
139
|
+
|
140
|
+
assert_equal 2, jamis.projects.size
|
141
|
+
assert_equal 2, jamis.projects(true).size
|
142
|
+
assert_equal 2, action_controller.developers(true).size
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_adding_type_mismatch
|
146
|
+
jamis = Developer.find(2)
|
147
|
+
assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << nil }
|
148
|
+
assert_raise(ActiveRecord::AssociationTypeMismatch) { jamis.projects << 1 }
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_adding_from_the_project
|
152
|
+
jamis = Developer.find(2)
|
153
|
+
action_controller = Project.find(2)
|
154
|
+
action_controller.developers.reload
|
155
|
+
assert_equal 1, jamis.projects.size
|
156
|
+
assert_equal 1, action_controller.developers.size
|
157
|
+
|
158
|
+
action_controller.developers << jamis
|
159
|
+
|
160
|
+
assert_equal 2, jamis.projects(true).size
|
161
|
+
assert_equal 2, action_controller.developers.size
|
162
|
+
assert_equal 2, action_controller.developers(true).size
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_adding_from_the_project_fixed_timestamp
|
166
|
+
jamis = Developer.find(2)
|
167
|
+
action_controller = Project.find(2)
|
168
|
+
action_controller.developers.reload
|
169
|
+
assert_equal 1, jamis.projects.size
|
170
|
+
assert_equal 1, action_controller.developers.size
|
171
|
+
updated_at = jamis.updated_at
|
172
|
+
|
173
|
+
action_controller.developers << jamis
|
174
|
+
|
175
|
+
assert_equal updated_at, jamis.updated_at
|
176
|
+
assert_equal 2, jamis.projects(true).size
|
177
|
+
assert_equal 2, action_controller.developers.size
|
178
|
+
assert_equal 2, action_controller.developers(true).size
|
179
|
+
end
|
180
|
+
|
181
|
+
def test_adding_multiple
|
182
|
+
aredridel = Developer.new("name" => "Aredridel")
|
183
|
+
aredridel.save
|
184
|
+
aredridel.projects.reload
|
185
|
+
aredridel.projects.push(Project.find(1), Project.find(2))
|
186
|
+
assert_equal 2, aredridel.projects.size
|
187
|
+
assert_equal 2, aredridel.projects(true).size
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_adding_a_collection
|
191
|
+
aredridel = Developer.new("name" => "Aredridel")
|
192
|
+
aredridel.save
|
193
|
+
aredridel.projects.reload
|
194
|
+
aredridel.projects.concat([Project.find(1), Project.find(2)])
|
195
|
+
assert_equal 2, aredridel.projects.size
|
196
|
+
assert_equal 2, aredridel.projects(true).size
|
197
|
+
end
|
198
|
+
|
199
|
+
def test_habtm_adding_before_save
|
200
|
+
no_of_devels = Developer.count
|
201
|
+
no_of_projects = Project.count
|
202
|
+
aredridel = Developer.new("name" => "Aredridel")
|
203
|
+
aredridel.projects.concat([Project.find(1), p = Project.new("name" => "Projekt")])
|
204
|
+
assert !aredridel.persisted?
|
205
|
+
assert !p.persisted?
|
206
|
+
assert aredridel.save
|
207
|
+
assert aredridel.persisted?
|
208
|
+
assert_equal no_of_devels+1, Developer.count
|
209
|
+
assert_equal no_of_projects+1, Project.count
|
210
|
+
assert_equal 2, aredridel.projects.size
|
211
|
+
assert_equal 2, aredridel.projects(true).size
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_habtm_saving_multiple_relationships
|
215
|
+
new_project = Project.new("name" => "Grimetime")
|
216
|
+
amount_of_developers = 4
|
217
|
+
developers = (0...amount_of_developers).collect {|i| Developer.create(:name => "JME #{i}") }.reverse
|
218
|
+
|
219
|
+
new_project.developer_ids = [developers[0].id, developers[1].id]
|
220
|
+
new_project.developers_with_callback_ids = [developers[2].id, developers[3].id]
|
221
|
+
assert new_project.save
|
222
|
+
|
223
|
+
new_project.reload
|
224
|
+
assert_equal amount_of_developers, new_project.developers.size
|
225
|
+
assert_equal developers, new_project.developers
|
226
|
+
end
|
227
|
+
|
228
|
+
def test_habtm_unique_order_preserved
|
229
|
+
assert_equal developers(:poor_jamis, :jamis, :david), projects(:active_record).non_unique_developers
|
230
|
+
assert_equal developers(:poor_jamis, :jamis, :david), projects(:active_record).developers
|
231
|
+
end
|
232
|
+
|
233
|
+
def test_build
|
234
|
+
devel = Developer.find(1)
|
235
|
+
proj = assert_no_queries { devel.projects.build("name" => "Projekt") }
|
236
|
+
assert !devel.projects.loaded?
|
237
|
+
|
238
|
+
assert_equal devel.projects.last, proj
|
239
|
+
assert devel.projects.loaded?
|
240
|
+
|
241
|
+
assert !proj.persisted?
|
242
|
+
devel.save
|
243
|
+
assert proj.persisted?
|
244
|
+
assert_equal devel.projects.last, proj
|
245
|
+
assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
|
246
|
+
end
|
247
|
+
|
248
|
+
def test_new_aliased_to_build
|
249
|
+
devel = Developer.find(1)
|
250
|
+
proj = assert_no_queries { devel.projects.new("name" => "Projekt") }
|
251
|
+
assert !devel.projects.loaded?
|
252
|
+
|
253
|
+
assert_equal devel.projects.last, proj
|
254
|
+
assert devel.projects.loaded?
|
255
|
+
|
256
|
+
assert !proj.persisted?
|
257
|
+
devel.save
|
258
|
+
assert proj.persisted?
|
259
|
+
assert_equal devel.projects.last, proj
|
260
|
+
assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
|
261
|
+
end
|
262
|
+
|
263
|
+
def test_build_by_new_record
|
264
|
+
devel = Developer.new(:name => "Marcel", :salary => 75000)
|
265
|
+
devel.projects.build(:name => "Make bed")
|
266
|
+
proj2 = devel.projects.build(:name => "Lie in it")
|
267
|
+
assert_equal devel.projects.last, proj2
|
268
|
+
assert !proj2.persisted?
|
269
|
+
devel.save
|
270
|
+
assert devel.persisted?
|
271
|
+
assert proj2.persisted?
|
272
|
+
assert_equal devel.projects.last, proj2
|
273
|
+
assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
|
274
|
+
end
|
275
|
+
|
276
|
+
def test_create
|
277
|
+
devel = Developer.find(1)
|
278
|
+
proj = devel.projects.create("name" => "Projekt")
|
279
|
+
assert !devel.projects.loaded?
|
280
|
+
|
281
|
+
assert_equal devel.projects.last, proj
|
282
|
+
assert !devel.projects.loaded?
|
283
|
+
|
284
|
+
assert proj.persisted?
|
285
|
+
assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
|
286
|
+
end
|
287
|
+
|
288
|
+
def test_create_by_new_record
|
289
|
+
devel = Developer.new(:name => "Marcel", :salary => 75000)
|
290
|
+
devel.projects.build(:name => "Make bed")
|
291
|
+
proj2 = devel.projects.build(:name => "Lie in it")
|
292
|
+
assert_equal devel.projects.last, proj2
|
293
|
+
assert !proj2.persisted?
|
294
|
+
devel.save
|
295
|
+
assert devel.persisted?
|
296
|
+
assert proj2.persisted?
|
297
|
+
assert_equal devel.projects.last, proj2
|
298
|
+
assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
|
299
|
+
end
|
300
|
+
|
301
|
+
def test_creation_respects_hash_condition
|
302
|
+
# in Oracle '' is saved as null therefore need to save ' ' in not null column
|
303
|
+
post = categories(:general).post_with_conditions.build(:body => ' ')
|
304
|
+
|
305
|
+
assert post.save
|
306
|
+
assert_equal 'Yet Another Testing Title', post.title
|
307
|
+
|
308
|
+
# in Oracle '' is saved as null therefore need to save ' ' in not null column
|
309
|
+
another_post = categories(:general).post_with_conditions.create(:body => ' ')
|
310
|
+
|
311
|
+
assert another_post.persisted?
|
312
|
+
assert_equal 'Yet Another Testing Title', another_post.title
|
313
|
+
end
|
314
|
+
|
315
|
+
def test_uniq_after_the_fact
|
316
|
+
dev = developers(:jamis)
|
317
|
+
dev.projects << projects(:active_record)
|
318
|
+
dev.projects << projects(:active_record)
|
319
|
+
|
320
|
+
assert_equal 3, dev.projects.size
|
321
|
+
assert_equal 1, dev.projects.uniq.size
|
322
|
+
end
|
323
|
+
|
324
|
+
def test_uniq_before_the_fact
|
325
|
+
projects(:active_record).developers << developers(:jamis)
|
326
|
+
projects(:active_record).developers << developers(:david)
|
327
|
+
assert_equal 3, projects(:active_record, :reload).developers.size
|
328
|
+
end
|
329
|
+
|
330
|
+
def test_uniq_option_prevents_duplicate_push
|
331
|
+
project = projects(:active_record)
|
332
|
+
project.developers << developers(:jamis)
|
333
|
+
project.developers << developers(:david)
|
334
|
+
assert_equal 3, project.developers.size
|
335
|
+
|
336
|
+
project.developers << developers(:david)
|
337
|
+
project.developers << developers(:jamis)
|
338
|
+
assert_equal 3, project.developers.size
|
339
|
+
end
|
340
|
+
|
341
|
+
def test_deleting
|
342
|
+
david = Developer.find(1)
|
343
|
+
active_record = Project.find(1)
|
344
|
+
david.projects.reload
|
345
|
+
assert_equal 2, david.projects.size
|
346
|
+
assert_equal 3, active_record.developers.size
|
347
|
+
|
348
|
+
david.projects.delete(active_record)
|
349
|
+
|
350
|
+
assert_equal 1, david.projects.size
|
351
|
+
assert_equal 1, david.projects(true).size
|
352
|
+
assert_equal 2, active_record.developers(true).size
|
353
|
+
end
|
354
|
+
|
355
|
+
def test_deleting_array
|
356
|
+
david = Developer.find(1)
|
357
|
+
david.projects.reload
|
358
|
+
david.projects.delete(Project.find(:all))
|
359
|
+
assert_equal 0, david.projects.size
|
360
|
+
assert_equal 0, david.projects(true).size
|
361
|
+
end
|
362
|
+
|
363
|
+
def test_deleting_with_sql
|
364
|
+
david = Developer.find(1)
|
365
|
+
active_record = Project.find(1)
|
366
|
+
active_record.developers.reload
|
367
|
+
assert_equal 3, active_record.developers_by_sql.size
|
368
|
+
|
369
|
+
active_record.developers_by_sql.delete(david)
|
370
|
+
assert_equal 2, active_record.developers_by_sql(true).size
|
371
|
+
end
|
372
|
+
|
373
|
+
def test_deleting_array_with_sql
|
374
|
+
active_record = Project.find(1)
|
375
|
+
active_record.developers.reload
|
376
|
+
assert_equal 3, active_record.developers_by_sql.size
|
377
|
+
|
378
|
+
active_record.developers_by_sql.delete(Developer.find(:all))
|
379
|
+
assert_equal 0, active_record.developers_by_sql(true).size
|
380
|
+
end
|
381
|
+
|
382
|
+
def test_deleting_all
|
383
|
+
david = Developer.find(1)
|
384
|
+
david.projects.reload
|
385
|
+
david.projects.clear
|
386
|
+
assert_equal 0, david.projects.size
|
387
|
+
assert_equal 0, david.projects(true).size
|
388
|
+
end
|
389
|
+
|
390
|
+
def test_removing_associations_on_destroy
|
391
|
+
david = DeveloperWithBeforeDestroyRaise.find(1)
|
392
|
+
assert !david.projects.empty?
|
393
|
+
david.destroy
|
394
|
+
assert david.projects.empty?
|
395
|
+
assert DeveloperWithBeforeDestroyRaise.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = 1").empty?
|
396
|
+
end
|
397
|
+
|
398
|
+
def test_destroying
|
399
|
+
david = Developer.find(1)
|
400
|
+
project = Project.find(1)
|
401
|
+
david.projects.reload
|
402
|
+
assert_equal 2, david.projects.size
|
403
|
+
assert_equal 3, project.developers.size
|
404
|
+
|
405
|
+
assert_no_difference "Project.count" do
|
406
|
+
david.projects.destroy(project)
|
407
|
+
end
|
408
|
+
|
409
|
+
join_records = Developer.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = #{david.id} AND project_id = #{project.id}")
|
410
|
+
assert join_records.empty?
|
411
|
+
|
412
|
+
assert_equal 1, david.reload.projects.size
|
413
|
+
assert_equal 1, david.projects(true).size
|
414
|
+
end
|
415
|
+
|
416
|
+
def test_destroying_many
|
417
|
+
david = Developer.find(1)
|
418
|
+
david.projects.reload
|
419
|
+
projects = Project.all
|
420
|
+
|
421
|
+
assert_no_difference "Project.count" do
|
422
|
+
david.projects.destroy(*projects)
|
423
|
+
end
|
424
|
+
|
425
|
+
join_records = Developer.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = #{david.id}")
|
426
|
+
assert join_records.empty?
|
427
|
+
|
428
|
+
assert_equal 0, david.reload.projects.size
|
429
|
+
assert_equal 0, david.projects(true).size
|
430
|
+
end
|
431
|
+
|
432
|
+
def test_destroy_all
|
433
|
+
david = Developer.find(1)
|
434
|
+
david.projects.reload
|
435
|
+
assert !david.projects.empty?
|
436
|
+
|
437
|
+
assert_no_difference "Project.count" do
|
438
|
+
david.projects.destroy_all
|
439
|
+
end
|
440
|
+
|
441
|
+
join_records = Developer.connection.select_all("SELECT * FROM developers_projects WHERE developer_id = #{david.id}")
|
442
|
+
assert join_records.empty?
|
443
|
+
|
444
|
+
assert david.projects.empty?
|
445
|
+
assert david.projects(true).empty?
|
446
|
+
end
|
447
|
+
|
448
|
+
def test_destroy_associations_destroys_multiple_associations
|
449
|
+
george = parrots(:george)
|
450
|
+
assert !george.pirates.empty?
|
451
|
+
assert !george.treasures.empty?
|
452
|
+
|
453
|
+
assert_no_difference "Pirate.count" do
|
454
|
+
assert_no_difference "Treasure.count" do
|
455
|
+
george.destroy_associations
|
456
|
+
end
|
457
|
+
end
|
458
|
+
|
459
|
+
join_records = Parrot.connection.select_all("SELECT * FROM parrots_pirates WHERE parrot_id = #{george.id}")
|
460
|
+
assert join_records.empty?
|
461
|
+
assert george.pirates(true).empty?
|
462
|
+
|
463
|
+
join_records = Parrot.connection.select_all("SELECT * FROM parrots_treasures WHERE parrot_id = #{george.id}")
|
464
|
+
assert join_records.empty?
|
465
|
+
assert george.treasures(true).empty?
|
466
|
+
end
|
467
|
+
|
468
|
+
def test_deprecated_push_with_attributes_was_removed
|
469
|
+
jamis = developers(:jamis)
|
470
|
+
assert_raise(NoMethodError) do
|
471
|
+
jamis.projects.push_with_attributes(projects(:action_controller), :joined_on => Date.today)
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
def test_associations_with_conditions
|
476
|
+
assert_equal 3, projects(:active_record).developers.size
|
477
|
+
assert_equal 1, projects(:active_record).developers_named_david.size
|
478
|
+
assert_equal 1, projects(:active_record).developers_named_david_with_hash_conditions.size
|
479
|
+
|
480
|
+
assert_equal developers(:david), projects(:active_record).developers_named_david.find(developers(:david).id)
|
481
|
+
assert_equal developers(:david), projects(:active_record).developers_named_david_with_hash_conditions.find(developers(:david).id)
|
482
|
+
assert_equal developers(:david), projects(:active_record).salaried_developers.find(developers(:david).id)
|
483
|
+
|
484
|
+
projects(:active_record).developers_named_david.clear
|
485
|
+
assert_equal 2, projects(:active_record, :reload).developers.size
|
486
|
+
end
|
487
|
+
|
488
|
+
def test_find_in_association
|
489
|
+
# Using sql
|
490
|
+
assert_equal developers(:david), projects(:active_record).developers.find(developers(:david).id), "SQL find"
|
491
|
+
|
492
|
+
# Using ruby
|
493
|
+
active_record = projects(:active_record)
|
494
|
+
active_record.developers.reload
|
495
|
+
assert_equal developers(:david), active_record.developers.find(developers(:david).id), "Ruby find"
|
496
|
+
end
|
497
|
+
|
498
|
+
def test_include_uses_array_include_after_loaded
|
499
|
+
project = projects(:active_record)
|
500
|
+
project.developers.class # force load target
|
501
|
+
|
502
|
+
developer = project.developers.first
|
503
|
+
|
504
|
+
assert_no_queries do
|
505
|
+
assert project.developers.loaded?
|
506
|
+
assert project.developers.include?(developer)
|
507
|
+
end
|
508
|
+
end
|
509
|
+
|
510
|
+
def test_include_checks_if_record_exists_if_target_not_loaded
|
511
|
+
project = projects(:active_record)
|
512
|
+
developer = project.developers.first
|
513
|
+
|
514
|
+
project.reload
|
515
|
+
assert ! project.developers.loaded?
|
516
|
+
assert_queries(1) do
|
517
|
+
assert project.developers.include?(developer)
|
518
|
+
end
|
519
|
+
assert ! project.developers.loaded?
|
520
|
+
end
|
521
|
+
|
522
|
+
def test_include_returns_false_for_non_matching_record_to_verify_scoping
|
523
|
+
project = projects(:active_record)
|
524
|
+
developer = Developer.create :name => "Bryan", :salary => 50_000
|
525
|
+
|
526
|
+
assert ! project.developers.loaded?
|
527
|
+
assert ! project.developers.include?(developer)
|
528
|
+
end
|
529
|
+
|
530
|
+
def test_find_in_association_with_custom_finder_sql
|
531
|
+
assert_equal developers(:david), projects(:active_record).developers_with_finder_sql.find(developers(:david).id), "SQL find"
|
532
|
+
|
533
|
+
active_record = projects(:active_record)
|
534
|
+
active_record.developers_with_finder_sql.reload
|
535
|
+
assert_equal developers(:david), active_record.developers_with_finder_sql.find(developers(:david).id), "Ruby find"
|
536
|
+
end
|
537
|
+
|
538
|
+
def test_find_in_association_with_custom_finder_sql_and_multiple_interpolations
|
539
|
+
# interpolate once:
|
540
|
+
assert_equal [developers(:david), developers(:jamis), developers(:poor_jamis)], projects(:active_record).developers_with_finder_sql, "first interpolation"
|
541
|
+
# interpolate again, for a different project id
|
542
|
+
assert_equal [developers(:david)], projects(:action_controller).developers_with_finder_sql, "second interpolation"
|
543
|
+
end
|
544
|
+
|
545
|
+
def test_find_in_association_with_custom_finder_sql_and_string_id
|
546
|
+
assert_equal developers(:david), projects(:active_record).developers_with_finder_sql.find(developers(:david).id.to_s), "SQL find"
|
547
|
+
end
|
548
|
+
|
549
|
+
def test_find_with_merged_options
|
550
|
+
assert_equal 1, projects(:active_record).limited_developers.size
|
551
|
+
assert_equal 1, projects(:active_record).limited_developers.find(:all).size
|
552
|
+
assert_equal 3, projects(:active_record).limited_developers.find(:all, :limit => nil).size
|
553
|
+
end
|
554
|
+
|
555
|
+
def test_dynamic_find_should_respect_association_order
|
556
|
+
# Developers are ordered 'name DESC, id DESC'
|
557
|
+
high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
|
558
|
+
|
559
|
+
assert_equal high_id_jamis, projects(:active_record).developers.find(:first, :conditions => "name = 'Jamis'")
|
560
|
+
assert_equal high_id_jamis, projects(:active_record).developers.find_by_name('Jamis')
|
561
|
+
end
|
562
|
+
|
563
|
+
def test_dynamic_find_all_should_respect_association_order
|
564
|
+
# Developers are ordered 'name DESC, id DESC'
|
565
|
+
low_id_jamis = developers(:jamis)
|
566
|
+
middle_id_jamis = developers(:poor_jamis)
|
567
|
+
high_id_jamis = projects(:active_record).developers.create(:name => 'Jamis')
|
568
|
+
|
569
|
+
assert_equal [high_id_jamis, middle_id_jamis, low_id_jamis], projects(:active_record).developers.find(:all, :conditions => "name = 'Jamis'")
|
570
|
+
assert_equal [high_id_jamis, middle_id_jamis, low_id_jamis], projects(:active_record).developers.find_all_by_name('Jamis')
|
571
|
+
end
|
572
|
+
|
573
|
+
def test_find_should_append_to_association_order
|
574
|
+
ordered_developers = projects(:active_record).developers.order('projects.id')
|
575
|
+
assert_equal ['developers.name desc, developers.id desc', 'projects.id'], ordered_developers.order_values
|
576
|
+
end
|
577
|
+
|
578
|
+
def test_dynamic_find_all_should_respect_association_limit
|
579
|
+
assert_equal 1, projects(:active_record).limited_developers.find(:all, :conditions => "name = 'Jamis'").length
|
580
|
+
assert_equal 1, projects(:active_record).limited_developers.find_all_by_name('Jamis').length
|
581
|
+
end
|
582
|
+
|
583
|
+
def test_dynamic_find_all_order_should_override_association_limit
|
584
|
+
assert_equal 2, projects(:active_record).limited_developers.find(:all, :conditions => "name = 'Jamis'", :limit => 9_000).length
|
585
|
+
assert_equal 2, projects(:active_record).limited_developers.find_all_by_name('Jamis', :limit => 9_000).length
|
586
|
+
end
|
587
|
+
|
588
|
+
def test_dynamic_find_all_should_respect_readonly_access
|
589
|
+
projects(:active_record).readonly_developers.each { |d| assert_raise(ActiveRecord::ReadOnlyRecord) { d.save! } if d.valid?}
|
590
|
+
projects(:active_record).readonly_developers.each { |d| d.readonly? }
|
591
|
+
end
|
592
|
+
|
593
|
+
def test_new_with_values_in_collection
|
594
|
+
jamis = DeveloperForProjectWithAfterCreateHook.find_by_name('Jamis')
|
595
|
+
david = DeveloperForProjectWithAfterCreateHook.find_by_name('David')
|
596
|
+
project = ProjectWithAfterCreateHook.new(:name => "Cooking with Bertie")
|
597
|
+
project.developers << jamis
|
598
|
+
project.save!
|
599
|
+
project.reload
|
600
|
+
|
601
|
+
assert project.developers.include?(jamis)
|
602
|
+
assert project.developers.include?(david)
|
603
|
+
end
|
604
|
+
|
605
|
+
def test_find_in_association_with_options
|
606
|
+
developers = projects(:active_record).developers.all
|
607
|
+
assert_equal 3, developers.size
|
608
|
+
|
609
|
+
assert_equal developers(:poor_jamis), projects(:active_record).developers.where("salary < 10000").first
|
610
|
+
end
|
611
|
+
|
612
|
+
def test_replace_with_less
|
613
|
+
david = developers(:david)
|
614
|
+
david.projects = [projects(:action_controller)]
|
615
|
+
assert david.save
|
616
|
+
assert_equal 1, david.projects.length
|
617
|
+
end
|
618
|
+
|
619
|
+
def test_replace_with_new
|
620
|
+
david = developers(:david)
|
621
|
+
david.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")]
|
622
|
+
david.save
|
623
|
+
assert_equal 2, david.projects.length
|
624
|
+
assert !david.projects.include?(projects(:active_record))
|
625
|
+
end
|
626
|
+
|
627
|
+
def test_replace_on_new_object
|
628
|
+
new_developer = Developer.new("name" => "Matz")
|
629
|
+
new_developer.projects = [projects(:action_controller), Project.new("name" => "ActionWebSearch")]
|
630
|
+
new_developer.save
|
631
|
+
assert_equal 2, new_developer.projects.length
|
632
|
+
end
|
633
|
+
|
634
|
+
def test_consider_type
|
635
|
+
developer = Developer.find(:first)
|
636
|
+
special_project = SpecialProject.create("name" => "Special Project")
|
637
|
+
|
638
|
+
other_project = developer.projects.first
|
639
|
+
developer.special_projects << special_project
|
640
|
+
developer.reload
|
641
|
+
|
642
|
+
assert developer.projects.include?(special_project)
|
643
|
+
assert developer.special_projects.include?(special_project)
|
644
|
+
assert !developer.special_projects.include?(other_project)
|
645
|
+
end
|
646
|
+
|
647
|
+
def test_update_attributes_after_push_without_duplicate_join_table_rows
|
648
|
+
developer = Developer.new("name" => "Kano")
|
649
|
+
project = SpecialProject.create("name" => "Special Project")
|
650
|
+
assert developer.save
|
651
|
+
developer.projects << project
|
652
|
+
developer.update_column("name", "Bruza")
|
653
|
+
assert_equal 1, Developer.connection.select_value(<<-end_sql).to_i
|
654
|
+
SELECT count(*) FROM developers_projects
|
655
|
+
WHERE project_id = #{project.id}
|
656
|
+
AND developer_id = #{developer.id}
|
657
|
+
end_sql
|
658
|
+
end
|
659
|
+
|
660
|
+
def test_updating_attributes_on_non_rich_associations
|
661
|
+
welcome = categories(:technology).posts.first
|
662
|
+
welcome.title = "Something else"
|
663
|
+
assert welcome.save!
|
664
|
+
end
|
665
|
+
|
666
|
+
def test_habtm_respects_select
|
667
|
+
categories(:technology).select_testing_posts(true).each do |o|
|
668
|
+
assert_respond_to o, :correctness_marker
|
669
|
+
end
|
670
|
+
assert_respond_to categories(:technology).select_testing_posts.find(:first), :correctness_marker
|
671
|
+
end
|
672
|
+
|
673
|
+
def test_habtm_selects_all_columns_by_default
|
674
|
+
assert_equal Project.column_names.sort, developers(:david).projects.first.attributes.keys.sort
|
675
|
+
end
|
676
|
+
|
677
|
+
def test_habtm_respects_select_query_method
|
678
|
+
assert_equal ['id'], developers(:david).projects.select(:id).first.attributes.keys
|
679
|
+
end
|
680
|
+
|
681
|
+
def test_join_table_alias
|
682
|
+
assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL').size
|
683
|
+
end
|
684
|
+
|
685
|
+
def test_join_with_group
|
686
|
+
group = Developer.columns.inject([]) do |g, c|
|
687
|
+
g << "developers.#{c.name}"
|
688
|
+
g << "developers_projects_2.#{c.name}"
|
689
|
+
end
|
690
|
+
Project.columns.each { |c| group << "projects.#{c.name}" }
|
691
|
+
|
692
|
+
assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL', :group => group.join(",")).size
|
693
|
+
end
|
694
|
+
|
695
|
+
def test_find_grouped
|
696
|
+
all_posts_from_category1 = Post.find(:all, :conditions => "category_id = 1", :joins => :categories)
|
697
|
+
grouped_posts_of_category1 = Post.find(:all, :conditions => "category_id = 1", :group => "author_id", :select => 'count(posts.id) as posts_count', :joins => :categories)
|
698
|
+
assert_equal 5, all_posts_from_category1.size
|
699
|
+
assert_equal 2, grouped_posts_of_category1.size
|
700
|
+
end
|
701
|
+
|
702
|
+
def test_find_scoped_grouped
|
703
|
+
assert_equal 5, categories(:general).posts_grouped_by_title.size
|
704
|
+
assert_equal 1, categories(:technology).posts_grouped_by_title.size
|
705
|
+
end
|
706
|
+
|
707
|
+
def test_find_scoped_grouped_having
|
708
|
+
assert_equal 2, projects(:active_record).well_payed_salary_groups.size
|
709
|
+
assert projects(:active_record).well_payed_salary_groups.all? { |g| g.salary > 10000 }
|
710
|
+
end
|
711
|
+
|
712
|
+
def test_get_ids
|
713
|
+
assert_equal projects(:active_record, :action_controller).map(&:id).sort, developers(:david).project_ids.sort
|
714
|
+
assert_equal [projects(:active_record).id], developers(:jamis).project_ids
|
715
|
+
end
|
716
|
+
|
717
|
+
def test_get_ids_for_loaded_associations
|
718
|
+
developer = developers(:david)
|
719
|
+
developer.projects(true)
|
720
|
+
assert_queries(0) do
|
721
|
+
developer.project_ids
|
722
|
+
developer.project_ids
|
723
|
+
end
|
724
|
+
end
|
725
|
+
|
726
|
+
def test_get_ids_for_unloaded_associations_does_not_load_them
|
727
|
+
developer = developers(:david)
|
728
|
+
assert !developer.projects.loaded?
|
729
|
+
assert_equal projects(:active_record, :action_controller).map(&:id).sort, developer.project_ids.sort
|
730
|
+
assert !developer.projects.loaded?
|
731
|
+
end
|
732
|
+
|
733
|
+
def test_assign_ids
|
734
|
+
developer = Developer.new("name" => "Joe")
|
735
|
+
developer.project_ids = projects(:active_record, :action_controller).map(&:id)
|
736
|
+
developer.save
|
737
|
+
developer.reload
|
738
|
+
assert_equal 2, developer.projects.length
|
739
|
+
assert_equal [projects(:active_record), projects(:action_controller)].map(&:id).sort, developer.project_ids.sort
|
740
|
+
end
|
741
|
+
|
742
|
+
def test_assign_ids_ignoring_blanks
|
743
|
+
developer = Developer.new("name" => "Joe")
|
744
|
+
developer.project_ids = [projects(:active_record).id, nil, projects(:action_controller).id, '']
|
745
|
+
developer.save
|
746
|
+
developer.reload
|
747
|
+
assert_equal 2, developer.projects.length
|
748
|
+
assert_equal [projects(:active_record), projects(:action_controller)].map(&:id).sort, developer.project_ids.sort
|
749
|
+
end
|
750
|
+
|
751
|
+
def test_scoped_find_on_through_association_doesnt_return_read_only_records
|
752
|
+
tag = Post.find(1).tags.find_by_name("General")
|
753
|
+
|
754
|
+
assert_nothing_raised do
|
755
|
+
tag.save!
|
756
|
+
end
|
757
|
+
end
|
758
|
+
|
759
|
+
def test_has_many_through_polymorphic_has_manys_works
|
760
|
+
assert_equal [10, 20].to_set, pirates(:redbeard).treasure_estimates.map(&:price).to_set
|
761
|
+
end
|
762
|
+
|
763
|
+
def test_symbols_as_keys
|
764
|
+
developer = DeveloperWithSymbolsForKeys.new(:name => 'David')
|
765
|
+
project = ProjectWithSymbolsForKeys.new(:name => 'Rails Testing')
|
766
|
+
project.developers << developer
|
767
|
+
project.save!
|
768
|
+
|
769
|
+
assert_equal 1, project.developers.size
|
770
|
+
assert_equal 1, developer.projects.size
|
771
|
+
assert_equal developer, project.developers.find(:first)
|
772
|
+
assert_equal project, developer.projects.find(:first)
|
773
|
+
end
|
774
|
+
|
775
|
+
def test_self_referential_habtm_without_foreign_key_set_should_raise_exception
|
776
|
+
assert_raise(ActiveRecord::HasAndBelongsToManyAssociationForeignKeyNeeded) {
|
777
|
+
Member.class_eval do
|
778
|
+
has_and_belongs_to_many :friends, :class_name => "Member", :join_table => "member_friends"
|
779
|
+
end
|
780
|
+
}
|
781
|
+
end
|
782
|
+
|
783
|
+
def test_dynamic_find_should_respect_association_include
|
784
|
+
# SQL error in sort clause if :include is not included
|
785
|
+
# due to Unknown column 'authors.id'
|
786
|
+
assert Category.find(1).posts_with_authors_sorted_by_author_id.find_by_title('Welcome to the weblog')
|
787
|
+
end
|
788
|
+
|
789
|
+
def test_counting_on_habtm_association_and_not_array
|
790
|
+
david = Developer.find(1)
|
791
|
+
# Extra parameter just to make sure we aren't falling back to
|
792
|
+
# Array#count in Ruby >=1.8.7, which would raise an ArgumentError
|
793
|
+
assert_nothing_raised { david.projects.count(:all, :conditions => '1=1') }
|
794
|
+
end
|
795
|
+
|
796
|
+
def test_count
|
797
|
+
david = Developer.find(1)
|
798
|
+
assert_equal 2, david.projects.count
|
799
|
+
end
|
800
|
+
|
801
|
+
def test_count_with_counter_sql
|
802
|
+
developer = DeveloperWithCounterSQL.create(:name => 'tekin')
|
803
|
+
developer.project_ids = [projects(:active_record).id]
|
804
|
+
developer.save
|
805
|
+
developer.reload
|
806
|
+
assert_equal 1, developer.projects.count
|
807
|
+
end
|
808
|
+
|
809
|
+
unless current_adapter?(:PostgreSQLAdapter, :IBM_DBAdapter)
|
810
|
+
def test_count_with_finder_sql
|
811
|
+
assert_equal 3, projects(:active_record).developers_with_finder_sql.count
|
812
|
+
assert_equal 3, projects(:active_record).developers_with_multiline_finder_sql.count
|
813
|
+
end
|
814
|
+
end
|
815
|
+
|
816
|
+
def test_association_proxy_transaction_method_starts_transaction_in_association_class
|
817
|
+
Post.expects(:transaction)
|
818
|
+
Category.find(:first).posts.transaction do
|
819
|
+
# nothing
|
820
|
+
end
|
821
|
+
end
|
822
|
+
|
823
|
+
def test_caching_of_columns
|
824
|
+
david = Developer.find(1)
|
825
|
+
# clear cache possibly created by other tests
|
826
|
+
david.projects.reset_column_information
|
827
|
+
|
828
|
+
assert_queries(1) { david.projects.columns; david.projects.columns }
|
829
|
+
|
830
|
+
## and again to verify that reset_column_information clears the cache correctly
|
831
|
+
david.projects.reset_column_information
|
832
|
+
assert_queries(1) { david.projects.columns; david.projects.columns }
|
833
|
+
end
|
834
|
+
|
835
|
+
def test_attributes_are_being_set_when_initialized_from_habm_association_with_where_clause
|
836
|
+
new_developer = projects(:action_controller).developers.where(:name => "Marcelo").build
|
837
|
+
assert_equal new_developer.name, "Marcelo"
|
838
|
+
end
|
839
|
+
|
840
|
+
def test_attributes_are_being_set_when_initialized_from_habm_association_with_multiple_where_clauses
|
841
|
+
new_developer = projects(:action_controller).developers.where(:name => "Marcelo").where(:salary => 90_000).build
|
842
|
+
assert_equal new_developer.name, "Marcelo"
|
843
|
+
assert_equal new_developer.salary, 90_000
|
844
|
+
end
|
845
|
+
|
846
|
+
def test_include_method_in_has_and_belongs_to_many_association_should_return_true_for_instance_added_with_build
|
847
|
+
project = Project.new
|
848
|
+
developer = project.developers.build
|
849
|
+
assert project.developers.include?(developer)
|
850
|
+
end
|
851
|
+
end
|