diff options
Diffstat (limited to 'activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb')
-rw-r--r-- | activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb | 129 |
1 files changed, 123 insertions, 6 deletions
diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb index 8aee7ff40e..092e85949c 100644 --- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb @@ -1,5 +1,6 @@ require "cases/helper" require 'models/developer' +require 'models/computer' require 'models/project' require 'models/company' require 'models/customer' @@ -11,6 +12,7 @@ require 'models/author' require 'models/tag' require 'models/tagging' require 'models/parrot' +require 'models/person' require 'models/pirate' require 'models/treasure' require 'models/price_estimate' @@ -20,6 +22,10 @@ require 'models/membership' require 'models/sponsor' require 'models/country' require 'models/treaty' +require 'models/vertex' +require 'models/publisher' +require 'models/publisher/article' +require 'models/publisher/magazine' require 'active_support/core_ext/string/conversions' class ProjectWithAfterCreateHook < ActiveRecord::Base @@ -65,9 +71,21 @@ class DeveloperWithSymbolsForKeys < ActiveRecord::Base :foreign_key => "developer_id" end +class SubDeveloper < Developer + self.table_name = 'developers' + has_and_belongs_to_many :special_projects, + :join_table => 'developers_projects', + :foreign_key => "project_id", + :association_foreign_key => "developer_id" +end + +class DeveloperWithSymbolClassName < Developer + has_and_belongs_to_many :projects, class_name: :ProjectWithSymbolsForKeys +end + class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects, - :parrots, :pirates, :parrots_pirates, :treasures, :price_estimates, :tags, :taggings + :parrots, :pirates, :parrots_pirates, :treasures, :price_estimates, :tags, :taggings, :computers def setup_data_for_habtm_case ActiveRecord::Base.connection.execute('delete from countries_treaties') @@ -81,6 +99,12 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase country.treaties << treaty end + def test_marshal_dump + post = posts :welcome + preloaded = Post.includes(:categories).find post.id + assert_equal preloaded, Marshal.load(Marshal.dump(preloaded)) + end + def test_should_property_quote_string_primary_keys setup_data_for_habtm_case @@ -215,9 +239,27 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase assert_equal developers(:poor_jamis, :jamis, :david), projects(:active_record).developers end + def test_habtm_collection_size_from_build + devel = Developer.create("name" => "Fred Wu") + devel.projects << Project.create("name" => "Grimetime") + devel.projects.build + + assert_equal 2, devel.projects.size + end + + def test_habtm_collection_size_from_params + devel = Developer.new({ + projects_attributes: { + '0' => {} + } + }) + + assert_equal 1, devel.projects.size + end + def test_build devel = Developer.find(1) - proj = assert_no_queries { devel.projects.build("name" => "Projekt") } + proj = assert_no_queries(ignore_none: false) { devel.projects.build("name" => "Projekt") } assert !devel.projects.loaded? assert_equal devel.projects.last, proj @@ -232,7 +274,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase def test_new_aliased_to_build devel = Developer.find(1) - proj = assert_no_queries { devel.projects.new("name" => "Projekt") } + proj = assert_no_queries(ignore_none: false) { devel.projects.new("name" => "Projekt") } assert !devel.projects.loaded? assert_equal devel.projects.last, proj @@ -466,7 +508,7 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase developer = project.developers.first - assert_no_queries do + assert_no_queries(ignore_none: false) do assert project.developers.loaded? assert project.developers.include?(developer) end @@ -775,9 +817,19 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase assert project.developers.include?(developer) end - test "has and belongs to many associations on new records use null relations" do + def test_destruction_does_not_error_without_primary_key + redbeard = pirates(:redbeard) + george = parrots(:george) + redbeard.parrots << george + assert_equal 2, george.pirates.count + Pirate.includes(:parrots).where(parrot: redbeard.parrot).find(redbeard.id).destroy + assert_equal 1, george.pirates.count + assert_equal [], Pirate.where(id: redbeard.id) + end + + def test_has_and_belongs_to_many_associations_on_new_records_use_null_relations projects = Developer.new.projects - assert_no_queries do + assert_no_queries(ignore_none: false) do assert_equal [], projects assert_equal [], projects.where(title: 'omg') assert_equal [], projects.pluck(:title) @@ -785,4 +837,69 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase end end + def test_association_with_validate_false_does_not_run_associated_validation_callbacks_on_create + rich_person = RichPerson.new + + treasure = Treasure.new + treasure.rich_people << rich_person + treasure.valid? + + assert_equal 1, treasure.rich_people.size + assert_nil rich_person.first_name, 'should not run associated person validation on create when validate: false' + end + + def test_association_with_validate_false_does_not_run_associated_validation_callbacks_on_update + rich_person = RichPerson.create! + person_first_name = rich_person.first_name + assert_not_nil person_first_name + + treasure = Treasure.new + treasure.rich_people << rich_person + treasure.valid? + + assert_equal 1, treasure.rich_people.size + assert_equal person_first_name, rich_person.first_name, 'should not run associated person validation on update when validate: false' + end + + def test_custom_join_table + assert_equal 'edges', Vertex.reflect_on_association(:sources).join_table + end + + def test_has_and_belongs_to_many_in_a_namespaced_model_pointing_to_a_namespaced_model + magazine = Publisher::Magazine.create + article = Publisher::Article.create + magazine.articles << article + magazine.save + + assert_includes magazine.articles, article + end + + def test_has_and_belongs_to_many_in_a_namespaced_model_pointing_to_a_non_namespaced_model + article = Publisher::Article.create + tag = Tag.create + article.tags << tag + article.save + + assert_includes article.tags, tag + end + + def test_redefine_habtm + child = SubDeveloper.new("name" => "Aredridel") + child.special_projects << SpecialProject.new("name" => "Special Project") + assert child.save, 'child object should be saved' + end + + def test_habtm_with_reflection_using_class_name_and_fixtures + assert_not_nil Developer._reflections['shared_computers'] + # Checking the fixture for named association is important here, because it's the only way + # we've been able to reproduce this bug + assert_not_nil File.read(File.expand_path("../../../fixtures/developers.yml", __FILE__)).index("shared_computers") + assert_equal developers(:david).shared_computers.first, computers(:laptop) + end + + def test_with_symbol_class_name + assert_nothing_raised NoMethodError do + DeveloperWithSymbolClassName.new + end + end end |