2 require 'models/developer'
3 require 'models/project'
4 require 'models/company'
7 require 'models/computer'
8 require 'models/customer'
10 require 'models/categorization'
11 require 'models/category'
13 require 'models/author'
14 require 'models/comment'
16 require 'models/tagging'
17 require 'models/person'
18 require 'models/reader'
19 require 'models/parrot'
20 require 'models/pirate'
21 require 'models/treasure'
22 require 'models/price_estimate'
24 require 'models/member'
25 require 'models/membership'
26 require 'models/sponsor'
28 class ProjectWithAfterCreateHook
< ActiveRecord
::Base
29 set_table_name
'projects'
30 has_and_belongs_to_many
:developers,
31 :class_name => "DeveloperForProjectWithAfterCreateHook",
32 :join_table => "developers_projects",
33 :foreign_key => "project_id",
34 :association_foreign_key => "developer_id"
36 after_create
:add_david
39 david
= DeveloperForProjectWithAfterCreateHook
.find_by_name('David')
40 david
.projects
<< self
44 class DeveloperForProjectWithAfterCreateHook
< ActiveRecord
::Base
45 set_table_name
'developers'
46 has_and_belongs_to_many
:projects,
47 :class_name => "ProjectWithAfterCreateHook",
48 :join_table => "developers_projects",
49 :association_foreign_key => "project_id",
50 :foreign_key => "developer_id"
53 class ProjectWithSymbolsForKeys
< ActiveRecord
::Base
54 set_table_name
'projects'
55 has_and_belongs_to_many
:developers,
56 :class_name => "DeveloperWithSymbolsForKeys",
57 :join_table => :developers_projects,
58 :foreign_key => :project_id,
59 :association_foreign_key => "developer_id"
62 class DeveloperWithSymbolsForKeys
< ActiveRecord
::Base
63 set_table_name
'developers'
64 has_and_belongs_to_many
:projects,
65 :class_name => "ProjectWithSymbolsForKeys",
66 :join_table => :developers_projects,
67 :association_foreign_key => :project_id,
68 :foreign_key => "developer_id"
71 class DeveloperWithCounterSQL
< ActiveRecord
::Base
72 set_table_name
'developers'
73 has_and_belongs_to_many
:projects,
74 :class_name => "DeveloperWithCounterSQL",
75 :join_table => "developers_projects",
76 :association_foreign_key => "project_id",
77 :foreign_key => "developer_id",
78 :counter_sql => 'SELECT COUNT(*) AS count_all FROM projects INNER JOIN developers_projects ON projects.id = developers_projects.project_id WHERE developers_projects.developer_id =#{id}'
81 class HasAndBelongsToManyAssociationsTest
< ActiveRecord
::TestCase
82 fixtures
:accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects,
83 :parrots, :pirates, :treasures, :price_estimates, :tags, :taggings
85 def test_has_and_belongs_to_many
86 david
= Developer
.find(1)
88 assert
!david
.projects
.empty
?
89 assert_equal
2, david
.projects
.size
91 active_record
= Project
.find(1)
92 assert
!active_record
.developers
.empty
?
93 assert_equal
3, active_record
.developers
.size
94 assert active_record
.developers
.include?(david
)
97 def test_triple_equality
98 assert
!(Array
=== Developer
.find(1).projects
)
99 assert Developer
.find(1).projects
=== Array
102 def test_adding_single
103 jamis
= Developer
.find(2)
104 jamis
.projects
.reload
# causing the collection to load
105 action_controller
= Project
.find(2)
106 assert_equal
1, jamis
.projects
.size
107 assert_equal
1, action_controller
.developers
.size
109 jamis
.projects
<< action_controller
111 assert_equal
2, jamis
.projects
.size
112 assert_equal
2, jamis
.projects(true).size
113 assert_equal
2, action_controller
.developers(true).size
116 def test_adding_type_mismatch
117 jamis
= Developer
.find(2)
118 assert_raise(ActiveRecord
::AssociationTypeMismatch) { jamis
.projects
<< nil }
119 assert_raise(ActiveRecord
::AssociationTypeMismatch) { jamis
.projects
<< 1 }
122 def test_adding_from_the_project
123 jamis
= Developer
.find(2)
124 action_controller
= Project
.find(2)
125 action_controller
.developers
.reload
126 assert_equal
1, jamis
.projects
.size
127 assert_equal
1, action_controller
.developers
.size
129 action_controller
.developers
<< jamis
131 assert_equal
2, jamis
.projects(true).size
132 assert_equal
2, action_controller
.developers
.size
133 assert_equal
2, action_controller
.developers(true).size
136 def test_adding_from_the_project_fixed_timestamp
137 jamis
= Developer
.find(2)
138 action_controller
= Project
.find(2)
139 action_controller
.developers
.reload
140 assert_equal
1, jamis
.projects
.size
141 assert_equal
1, action_controller
.developers
.size
142 updated_at
= jamis
.updated_at
144 action_controller
.developers
<< jamis
146 assert_equal updated_at
, jamis
.updated_at
147 assert_equal
2, jamis
.projects(true).size
148 assert_equal
2, action_controller
.developers
.size
149 assert_equal
2, action_controller
.developers(true).size
152 def test_adding_multiple
153 aredridel
= Developer
.new("name" => "Aredridel")
155 aredridel
.projects
.reload
156 aredridel
.projects
.push(Project
.find(1), Project
.find(2))
157 assert_equal
2, aredridel
.projects
.size
158 assert_equal
2, aredridel
.projects(true).size
161 def test_adding_a_collection
162 aredridel
= Developer
.new("name" => "Aredridel")
164 aredridel
.projects
.reload
165 aredridel
.projects
.concat([Project
.find(1), Project
.find(2)])
166 assert_equal
2, aredridel
.projects
.size
167 assert_equal
2, aredridel
.projects(true).size
170 def test_adding_uses_default_values_on_join_table
171 ac
= projects(:action_controller)
172 assert
!developers(:jamis).projects
.include?(ac
)
173 developers(:jamis).projects
<< ac
175 assert
developers(:jamis, :reload).projects
.include?(ac
)
176 project
= developers(:jamis).projects
.detect
{ |p
| p
== ac
}
177 assert_equal
1, project
.access_level
.to_i
180 def test_habtm_attribute_access_and_respond_to
181 project
= developers(:jamis).projects
[0]
182 assert project
.has_attribute
?("name")
183 assert project
.has_attribute
?("joined_on")
184 assert project
.has_attribute
?("access_level")
185 assert project
.respond_to
?("name")
186 assert project
.respond_to
?("name=")
187 assert project
.respond_to
?("name?")
188 assert project
.respond_to
?("joined_on")
189 # given that the 'join attribute' won't be persisted, I don't
190 # think we should define the mutators
191 #assert project.respond_to?("joined_on=")
192 assert project
.respond_to
?("joined_on?")
193 assert project
.respond_to
?("access_level")
194 #assert project.respond_to?("access_level=")
195 assert project
.respond_to
?("access_level?")
198 def test_habtm_adding_before_save
199 no_of_devels
= Developer
.count
200 no_of_projects
= Project
.count
201 aredridel
= Developer
.new("name" => "Aredridel")
202 aredridel
.projects
.concat([Project
.find(1), p
= Project
.new("name" => "Projekt")])
203 assert aredridel
.new_record
?
205 assert aredridel
.save
206 assert
!aredridel
.new_record
?
207 assert_equal no_of_devels
+1, Developer
.count
208 assert_equal no_of_projects
+1, Project
.count
209 assert_equal
2, aredridel
.projects
.size
210 assert_equal
2, aredridel
.projects(true).size
213 def test_habtm_saving_multiple_relationships
214 new_project
= Project
.new("name" => "Grimetime")
215 amount_of_developers
= 4
216 developers
= (0...amount_of_developers
).collect
{|i
| Developer
.create(:name => "JME #{i}") }.reverse
218 new_project
.developer_ids
= [developers
[0].id
, developers
[1].id
]
219 new_project
.developers_with_callback_ids
= [developers
[2].id
, developers
[3].id
]
220 assert new_project
.save
223 assert_equal amount_of_developers
, new_project
.developers
.size
224 assert_equal developers
, new_project
.developers
227 def test_habtm_unique_order_preserved
228 assert_equal
developers(:poor_jamis, :jamis, :david), projects(:active_record).non_unique_developers
229 assert_equal
developers(:poor_jamis, :jamis, :david), projects(:active_record).developers
233 devel
= Developer
.find(1)
234 proj
= assert_no_queries
{ devel
.projects
.build("name" => "Projekt") }
235 assert
!devel
.projects
.loaded
?
237 assert_equal devel
.projects
.last
, proj
238 assert devel
.projects
.loaded
?
240 assert proj
.new_record
?
242 assert
!proj
.new_record
?
243 assert_equal devel
.projects
.last
, proj
244 assert_equal Developer
.find(1).projects
.sort_by(&:id).last
, proj
# prove join table is updated
247 def test_build_by_new_record
248 devel
= Developer
.new(:name => "Marcel", :salary => 75000)
249 proj1
= devel
.projects
.build(:name => "Make bed")
250 proj2
= devel
.projects
.build(:name => "Lie in it")
251 assert_equal devel
.projects
.last
, proj2
252 assert proj2
.new_record
?
254 assert
!devel
.new_record
?
255 assert
!proj2
.new_record
?
256 assert_equal devel
.projects
.last
, proj2
257 assert_equal Developer
.find_by_name("Marcel").projects
.last
, proj2
# prove join table is updated
261 devel
= Developer
.find(1)
262 proj
= devel
.projects
.create("name" => "Projekt")
263 assert
!devel
.projects
.loaded
?
265 assert_equal devel
.projects
.last
, proj
266 assert
!devel
.projects
.loaded
?
268 assert
!proj
.new_record
?
269 assert_equal Developer
.find(1).projects
.sort_by(&:id).last
, proj
# prove join table is updated
272 def test_create_by_new_record
273 devel
= Developer
.new(:name => "Marcel", :salary => 75000)
274 proj1
= devel
.projects
.build(:name => "Make bed")
275 proj2
= devel
.projects
.build(:name => "Lie in it")
276 assert_equal devel
.projects
.last
, proj2
277 assert proj2
.new_record
?
279 assert
!devel
.new_record
?
280 assert
!proj2
.new_record
?
281 assert_equal devel
.projects
.last
, proj2
282 assert_equal Developer
.find_by_name("Marcel").projects
.last
, proj2
# prove join table is updated
285 def test_creation_respects_hash_condition
286 post
= categories(:general).post_with_conditions
.build(:body => '')
289 assert_equal
'Yet Another Testing Title', post
.title
291 another_post
= categories(:general).post_with_conditions
.create(:body => '')
293 assert
!another_post
.new_record
?
294 assert_equal
'Yet Another Testing Title', another_post
.title
297 def test_uniq_after_the_fact
298 dev
= developers(:jamis)
299 dev
.projects
<< projects(:active_record)
300 dev
.projects
<< projects(:active_record)
302 assert_equal
3, dev
.projects
.size
303 assert_equal
1, dev
.projects
.uniq
.size
306 def test_uniq_before_the_fact
307 projects(:active_record).developers
<< developers(:jamis)
308 projects(:active_record).developers
<< developers(:david)
309 assert_equal
3, projects(:active_record, :reload).developers
.size
312 def test_uniq_option_prevents_duplicate_push
313 project
= projects(:active_record)
314 project
.developers
<< developers(:jamis)
315 project
.developers
<< developers(:david)
316 assert_equal
3, project
.developers
.size
318 project
.developers
<< developers(:david)
319 project
.developers
<< developers(:jamis)
320 assert_equal
3, project
.developers
.size
324 david
= Developer
.find(1)
325 active_record
= Project
.find(1)
326 david
.projects
.reload
327 assert_equal
2, david
.projects
.size
328 assert_equal
3, active_record
.developers
.size
330 david
.projects
.delete(active_record
)
332 assert_equal
1, david
.projects
.size
333 assert_equal
1, david
.projects(true).size
334 assert_equal
2, active_record
.developers(true).size
337 def test_deleting_array
338 david
= Developer
.find(1)
339 david
.projects
.reload
340 david
.projects
.delete(Project
.find(:all))
341 assert_equal
0, david
.projects
.size
342 assert_equal
0, david
.projects(true).size
345 def test_deleting_with_sql
346 david
= Developer
.find(1)
347 active_record
= Project
.find(1)
348 active_record
.developers
.reload
349 assert_equal
3, active_record
.developers_by_sql
.size
351 active_record
.developers_by_sql
.delete(david
)
352 assert_equal
2, active_record
.developers_by_sql(true).size
355 def test_deleting_array_with_sql
356 active_record
= Project
.find(1)
357 active_record
.developers
.reload
358 assert_equal
3, active_record
.developers_by_sql
.size
360 active_record
.developers_by_sql
.delete(Developer
.find(:all))
361 assert_equal
0, active_record
.developers_by_sql(true).size
364 def test_deleting_all
365 david
= Developer
.find(1)
366 david
.projects
.reload
368 assert_equal
0, david
.projects
.size
369 assert_equal
0, david
.projects(true).size
372 def test_removing_associations_on_destroy
373 david
= DeveloperWithBeforeDestroyRaise
.find(1)
374 assert
!david
.projects
.empty
?
375 assert_nothing_raised
{ david
.destroy
}
376 assert david
.projects
.empty
?
377 assert DeveloperWithBeforeDestroyRaise
.connection
.select_all("SELECT * FROM developers_projects WHERE developer_id = 1").empty
?
380 def test_additional_columns_from_join_table
381 assert_date_from_db Date
.new(2004, 10, 10), Developer
.find(1).projects
.first
.joined_on
.to_date
385 david
= Developer
.find(1)
386 active_record
= Project
.find(1)
387 david
.projects
.reload
388 assert_equal
2, david
.projects
.size
389 assert_equal
3, active_record
.developers
.size
391 assert_difference
"Project.count", -1 do
392 david
.projects
.destroy(active_record
)
395 assert_equal
1, david
.reload
.projects
.size
396 assert_equal
1, david
.projects(true).size
399 def test_destroying_array
400 david
= Developer
.find(1)
401 david
.projects
.reload
403 assert_difference
"Project.count", -Project
.count
do
404 david
.projects
.destroy(Project
.find(:all))
407 assert_equal
0, david
.reload
.projects
.size
408 assert_equal
0, david
.projects(true).size
412 david
= Developer
.find(1)
413 david
.projects
.reload
414 assert
!david
.projects
.empty
?
415 david
.projects
.destroy_all
416 assert david
.projects
.empty
?
417 assert david
.projects(true).empty
?
420 def test_deprecated_push_with_attributes_was_removed
421 jamis
= developers(:jamis)
422 assert_raise(NoMethodError
) do
423 jamis
.projects
.push_with_attributes(projects(:action_controller), :joined_on => Date
.today
)
427 def test_associations_with_conditions
428 assert_equal
3, projects(:active_record).developers
.size
429 assert_equal
1, projects(:active_record).developers_named_david
.size
430 assert_equal
1, projects(:active_record).developers_named_david_with_hash_conditions
.size
432 assert_equal
developers(:david), projects(:active_record).developers_named_david
.find(developers(:david).id
)
433 assert_equal
developers(:david), projects(:active_record).developers_named_david_with_hash_conditions
.find(developers(:david).id
)
434 assert_equal
developers(:david), projects(:active_record).salaried_developers
.find(developers(:david).id
)
436 projects(:active_record).developers_named_david
.clear
437 assert_equal
2, projects(:active_record, :reload).developers
.size
440 def test_find_in_association
442 assert_equal
developers(:david), projects(:active_record).developers
.find(developers(:david).id
), "SQL find"
445 active_record
= projects(:active_record)
446 active_record
.developers
.reload
447 assert_equal
developers(:david), active_record
.developers
.find(developers(:david).id
), "Ruby find"
450 def test_include_uses_array_include_after_loaded
451 project
= projects(:active_record)
452 project
.developers
.class # force load target
454 developer
= project
.developers
.first
457 assert project
.developers
.loaded
?
458 assert project
.developers
.include?(developer
)
462 def test_include_checks_if_record_exists_if_target_not_loaded
463 project
= projects(:active_record)
464 developer
= project
.developers
.first
467 assert
! project
.developers
.loaded
?
469 assert project
.developers
.include?(developer
)
471 assert
! project
.developers
.loaded
?
474 def test_include_returns_false_for_non_matching_record_to_verify_scoping
475 project
= projects(:active_record)
476 developer
= Developer
.create
:name => "Bryan", :salary => 50_000
478 assert
! project
.developers
.loaded
?
479 assert
! project
.developers
.include?(developer
)
482 def test_find_in_association_with_custom_finder_sql
483 assert_equal
developers(:david), projects(:active_record).developers_with_finder_sql
.find(developers(:david).id
), "SQL find"
485 active_record
= projects(:active_record)
486 active_record
.developers_with_finder_sql
.reload
487 assert_equal
developers(:david), active_record
.developers_with_finder_sql
.find(developers(:david).id
), "Ruby find"
490 def test_find_in_association_with_custom_finder_sql_and_multiple_interpolations
492 assert_equal
[developers(:david), developers(:jamis), developers(:poor_jamis)], projects(:active_record).developers_with_finder_sql
, "first interpolation"
493 # interpolate again, for a different project id
494 assert_equal
[developers(:david)], projects(:action_controller).developers_with_finder_sql
, "second interpolation"
497 def test_find_in_association_with_custom_finder_sql_and_string_id
498 assert_equal
developers(:david), projects(:active_record).developers_with_finder_sql
.find(developers(:david).id
.to_s
), "SQL find"
501 def test_find_with_merged_options
502 assert_equal
1, projects(:active_record).limited_developers
.size
503 assert_equal
1, projects(:active_record).limited_developers
.find(:all).size
504 assert_equal
3, projects(:active_record).limited_developers
.find(:all, :limit => nil).size
507 def test_dynamic_find_should_respect_association_order
508 # Developers are ordered 'name DESC, id DESC'
509 low_id_jamis
= developers(:jamis)
510 middle_id_jamis
= developers(:poor_jamis)
511 high_id_jamis
= projects(:active_record).developers
.create(:name => 'Jamis')
513 assert_equal high_id_jamis
, projects(:active_record).developers
.find(:first, :conditions => "name = 'Jamis'")
514 assert_equal high_id_jamis
, projects(:active_record).developers
.find_by_name('Jamis')
517 def test_dynamic_find_order_should_override_association_order
518 # Developers are ordered 'name DESC, id DESC'
519 low_id_jamis
= developers(:jamis)
520 middle_id_jamis
= developers(:poor_jamis)
521 high_id_jamis
= projects(:active_record).developers
.create(:name => 'Jamis')
523 assert_equal low_id_jamis
, projects(:active_record).developers
.find(:first, :conditions => "name = 'Jamis'", :order => 'id')
524 assert_equal low_id_jamis
, projects(:active_record).developers
.find_by_name('Jamis', :order => 'id')
527 def test_dynamic_find_all_should_respect_association_order
528 # Developers are ordered 'name DESC, id DESC'
529 low_id_jamis
= developers(:jamis)
530 middle_id_jamis
= developers(:poor_jamis)
531 high_id_jamis
= projects(:active_record).developers
.create(:name => 'Jamis')
533 assert_equal
[high_id_jamis
, middle_id_jamis
, low_id_jamis
], projects(:active_record).developers
.find(:all, :conditions => "name = 'Jamis'")
534 assert_equal
[high_id_jamis
, middle_id_jamis
, low_id_jamis
], projects(:active_record).developers
.find_all_by_name('Jamis')
537 def test_dynamic_find_all_order_should_override_association_order
538 # Developers are ordered 'name DESC, id DESC'
539 low_id_jamis
= developers(:jamis)
540 middle_id_jamis
= developers(:poor_jamis)
541 high_id_jamis
= projects(:active_record).developers
.create(:name => 'Jamis')
543 assert_equal
[low_id_jamis
, middle_id_jamis
, high_id_jamis
], projects(:active_record).developers
.find(:all, :conditions => "name = 'Jamis'", :order => 'id')
544 assert_equal
[low_id_jamis
, middle_id_jamis
, high_id_jamis
], projects(:active_record).developers
.find_all_by_name('Jamis', :order => 'id')
547 def test_dynamic_find_all_should_respect_association_limit
548 assert_equal
1, projects(:active_record).limited_developers
.find(:all, :conditions => "name = 'Jamis'").length
549 assert_equal
1, projects(:active_record).limited_developers
.find_all_by_name('Jamis').length
552 def test_dynamic_find_all_order_should_override_association_limit
553 assert_equal
2, projects(:active_record).limited_developers
.find(:all, :conditions => "name = 'Jamis'", :limit => 9_000).length
554 assert_equal
2, projects(:active_record).limited_developers
.find_all_by_name('Jamis', :limit => 9_000).length
557 def test_dynamic_find_all_should_respect_readonly_access
558 projects(:active_record).readonly_developers
.each
{ |d
| assert_raise(ActiveRecord
::ReadOnlyRecord) { d
.save
! } if d
.valid
?}
559 projects(:active_record).readonly_developers
.each
{ |d
| d
.readonly
? }
562 def test_new_with_values_in_collection
563 jamis
= DeveloperForProjectWithAfterCreateHook
.find_by_name('Jamis')
564 david
= DeveloperForProjectWithAfterCreateHook
.find_by_name('David')
565 project
= ProjectWithAfterCreateHook
.new(:name => "Cooking with Bertie")
566 project
.developers
<< jamis
570 assert project
.developers
.include?(jamis
)
571 assert project
.developers
.include?(david
)
574 def test_find_in_association_with_options
575 developers
= projects(:active_record).developers
.find(:all)
576 assert_equal
3, developers
.size
578 assert_equal
developers(:poor_jamis), projects(:active_record).developers
.find(:first, :conditions => "salary < 10000")
579 assert_equal
developers(:jamis), projects(:active_record).developers
.find(:first, :order => "salary DESC")
582 def test_replace_with_less
583 david
= developers(:david)
584 david
.projects
= [projects(:action_controller)]
586 assert_equal
1, david
.projects
.length
589 def test_replace_with_new
590 david
= developers(:david)
591 david
.projects
= [projects(:action_controller), Project
.new("name" => "ActionWebSearch")]
593 assert_equal
2, david
.projects
.length
594 assert
!david
.projects
.include?(projects(:active_record))
597 def test_replace_on_new_object
598 new_developer
= Developer
.new("name" => "Matz")
599 new_developer
.projects
= [projects(:action_controller), Project
.new("name" => "ActionWebSearch")]
601 assert_equal
2, new_developer
.projects
.length
604 def test_consider_type
605 developer
= Developer
.find(:first)
606 special_project
= SpecialProject
.create("name" => "Special Project")
608 other_project
= developer
.projects
.first
609 developer
.special_projects
<< special_project
612 assert developer
.projects
.include?(special_project
)
613 assert developer
.special_projects
.include?(special_project
)
614 assert
!developer
.special_projects
.include?(other_project
)
617 def test_update_attributes_after_push_without_duplicate_join_table_rows
618 developer
= Developer
.new("name" => "Kano")
619 project
= SpecialProject
.create("name" => "Special Project")
620 assert developer
.save
621 developer
.projects
<< project
622 developer
.update_attribute("name", "Bruza")
623 assert_equal
1, Developer
.connection
.select_value(<<-end_sql).to_i
624 SELECT count(*) FROM developers_projects
625 WHERE project_id = #{project.id}
626 AND developer_id = #{developer.id}
630 def test_updating_attributes_on_non_rich_associations
631 welcome
= categories(:technology).posts
.first
632 welcome
.title
= "Something else"
636 def test_habtm_respects_select
637 categories(:technology).select_testing_posts(true).each
do |o
|
638 assert_respond_to o
, :correctness_marker
640 assert_respond_to
categories(:technology).select_testing_posts
.find(:first), :correctness_marker
643 def test_updating_attributes_on_rich_associations
644 david
= projects(:action_controller).developers
.first
646 assert_raise(ActiveRecord
::ReadOnlyRecord) { david
.save
! }
649 def test_updating_attributes_on_rich_associations_with_limited_find_from_reflection
650 david
= projects(:action_controller).selected_developers
.first
652 assert_nothing_raised
{ david
.save
! }
656 def test_updating_attributes_on_rich_associations_with_limited_find
657 david
= projects(:action_controller).developers
.find(:all, :select => "developers.*").first
662 def test_join_table_alias
663 assert_equal
3, Developer
.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL').size
666 def test_join_with_group
667 group
= Developer
.columns
.inject([]) do |g
, c
|
668 g
<< "developers.#{c.name}"
669 g
<< "developers_projects_2.#{c.name}"
671 Project
.columns
.each
{ |c
| group
<< "projects.#{c.name}" }
673 assert_equal
3, Developer
.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL', :group => group
.join(",")).size
676 def test_find_grouped
677 all_posts_from_category1
= Post
.find(:all, :conditions => "category_id = 1", :joins => :categories)
678 grouped_posts_of_category1
= Post
.find(:all, :conditions => "category_id = 1", :group => "author_id", :select => 'count(posts.id) as posts_count', :joins => :categories)
679 assert_equal
4, all_posts_from_category1
.size
680 assert_equal
1, grouped_posts_of_category1
.size
683 def test_find_scoped_grouped
684 assert_equal
4, categories(:general).posts_gruoped_by_title
.size
685 assert_equal
1, categories(:technology).posts_gruoped_by_title
.size
688 def test_find_scoped_grouped_having
689 assert_equal
2, projects(:active_record).well_payed_salary_groups
.size
690 assert
projects(:active_record).well_payed_salary_groups
.all
? { |g
| g
.salary
> 10000 }
694 assert_equal
projects(:active_record, :action_controller).map(&:id).sort
, developers(:david).project_ids
.sort
695 assert_equal
[projects(:active_record).id
], developers(:jamis).project_ids
698 def test_get_ids_for_loaded_associations
699 developer
= developers(:david)
700 developer
.projects(true)
702 developer
.project_ids
703 developer
.project_ids
707 def test_get_ids_for_unloaded_associations_does_not_load_them
708 developer
= developers(:david)
709 assert
!developer
.projects
.loaded
?
710 assert_equal
projects(:active_record, :action_controller).map(&:id).sort
, developer
.project_ids
.sort
711 assert
!developer
.projects
.loaded
?
715 developer
= Developer
.new("name" => "Joe")
716 developer
.project_ids
= projects(:active_record, :action_controller).map(&:id)
719 assert_equal
2, developer
.projects
.length
720 assert_equal
[projects(:active_record), projects(:action_controller)].map(&:id).sort
, developer
.project_ids
.sort
723 def test_assign_ids_ignoring_blanks
724 developer
= Developer
.new("name" => "Joe")
725 developer
.project_ids
= [projects(:active_record).id
, nil, projects(:action_controller).id
, '']
728 assert_equal
2, developer
.projects
.length
729 assert_equal
[projects(:active_record), projects(:action_controller)].map(&:id).sort
, developer
.project_ids
.sort
732 def test_select_limited_ids_list
734 Developer
.transaction
do
735 Developer
.find(:all, :order => 'id').each_with_index
do |record
, i
|
736 record
.update_attributes(:created_at => 5.years
.ago
+ (i
* 5.minutes
))
740 join_base
= ActiveRecord
::Associations::ClassMethods::JoinDependency::JoinBase.new(Project
)
741 join_dep
= ActiveRecord
::Associations::ClassMethods::JoinDependency.new(join_base
, :developers, nil)
742 projects
= Project
.send(:select_limited_ids_list, {:order => 'developers.created_at'}, join_dep
)
743 assert
!projects
.include?("'"), projects
744 assert_equal
%w(1 2), projects
.scan(/\d/).sort
747 def test_scoped_find_on_through_association_doesnt_return_read_only_records
748 tag
= Post
.find(1).tags
.find_by_name("General")
750 assert_nothing_raised
do
755 def test_has_many_through_polymorphic_has_manys_works
756 assert_equal
[10, 20].to_set
, pirates(:redbeard).treasure_estimates
.map(&:price).to_set
759 def test_symbols_as_keys
760 developer
= DeveloperWithSymbolsForKeys
.new(:name => 'David')
761 project
= ProjectWithSymbolsForKeys
.new(:name => 'Rails Testing')
762 project
.developers
<< developer
765 assert_equal
1, project
.developers
.size
766 assert_equal
1, developer
.projects
.size
767 assert_equal developer
, project
.developers
.find(:first)
768 assert_equal project
, developer
.projects
.find(:first)
771 def test_self_referential_habtm_without_foreign_key_set_should_raise_exception
772 assert_raise(ActiveRecord
::HasAndBelongsToManyAssociationForeignKeyNeeded) {
774 has_and_belongs_to_many
:friends, :class_name => "Member", :join_table => "member_friends"
779 def test_dynamic_find_should_respect_association_include
780 # SQL error in sort clause if :include is not included
781 # due to Unknown column 'authors.id'
782 assert Category
.find(1).posts_with_authors_sorted_by_author_id
.find_by_title('Welcome to the weblog')
785 def test_counting_on_habtm_association_and_not_array
786 david
= Developer
.find(1)
787 # Extra parameter just to make sure we aren't falling back to
788 # Array#count in Ruby >=1.8.7, which would raise an ArgumentError
789 assert_nothing_raised
{ david
.projects
.count(:all, :conditions => '1=1') }
793 david
= Developer
.find(1)
794 assert_equal
2, david
.projects
.count
797 def test_count_with_counter_sql
798 developer
= DeveloperWithCounterSQL
.create(:name => 'tekin')
799 developer
.project_ids
= [projects(:active_record).id
]
802 assert_equal
1, developer
.projects
.count
805 def test_association_proxy_transaction_method_starts_transaction_in_association_class
806 Post
.expects(:transaction)
807 Category
.find(:first).posts
.transaction
do
812 def test_caching_of_columns
813 david
= Developer
.find(1)
814 # clear cache possibly created by other tests
815 david
.projects
.reset_column_information
816 assert_queries(0) { david
.projects
.columns
; david
.projects
.columns
}
817 # and again to verify that reset_column_information clears the cache correctly
818 david
.projects
.reset_column_information
819 assert_queries(0) { david
.projects
.columns
; david
.projects
.columns
}