diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2014-11-09 15:07:56 -0800 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2014-11-09 15:07:56 -0800 |
commit | 049caa9e5a38ed8274a3d40a8b934012a87b464f (patch) | |
tree | f9d346387343f2c4b5241d2d7296993cbb47ed43 | |
parent | 47704af54d51b240f733c596ebb39a033aa698cd (diff) | |
parent | f43f56e16e99dae083cf1400a48c236d1af265d4 (diff) | |
download | rails-049caa9e5a38ed8274a3d40a8b934012a87b464f.tar.gz rails-049caa9e5a38ed8274a3d40a8b934012a87b464f.tar.bz2 rails-049caa9e5a38ed8274a3d40a8b934012a87b464f.zip |
Merge pull request #17217 from codeodor/fix-17119
Ensure HABTM relationships produce valid class names (Fixes #17119)
7 files changed, 25 insertions, 3 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 8911506694..d2bcdc55bf 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1700,7 +1700,7 @@ module ActiveRecord hm_options[:through] = middle_reflection.name hm_options[:source] = join_model.right_reflection.name - [:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate, :join_table].each do |k| + [:before_add, :after_add, :before_remove, :after_remove, :autosave, :validate, :join_table, :class_name].each do |k| hm_options[k] = options[k] if options.key? k end diff --git a/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb b/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb index 815e8eb97f..357b28ac94 100644 --- a/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb +++ b/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb @@ -98,7 +98,7 @@ module ActiveRecord::Associations::Builder def middle_options(join_model) middle_options = {} - middle_options[:class] = join_model + middle_options[:class_name] = "#{lhs_model.name}::#{join_model.name}" middle_options[:source] = join_model.left_reflection.name if options.key? :foreign_key middle_options[:foreign_key] = options[:foreign_key] 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 859310575e..9a57683ee3 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' @@ -80,7 +81,7 @@ 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') @@ -883,4 +884,12 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase 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 end diff --git a/activerecord/test/fixtures/computers.yml b/activerecord/test/fixtures/computers.yml index 7281a4d768..ad5ae2ec71 100644 --- a/activerecord/test/fixtures/computers.yml +++ b/activerecord/test/fixtures/computers.yml @@ -3,3 +3,8 @@ workstation: system: 'Linux' developer: 1 extendedWarranty: 1 + +laptop: + system: 'MacOS 1' + developer: 1 + extendedWarranty: 1 diff --git a/activerecord/test/fixtures/developers.yml b/activerecord/test/fixtures/developers.yml index 1a74563dc6..54b74e7a74 100644 --- a/activerecord/test/fixtures/developers.yml +++ b/activerecord/test/fixtures/developers.yml @@ -2,6 +2,7 @@ david: id: 1 name: David salary: 80000 + shared_computers: laptop jamis: id: 2 diff --git a/activerecord/test/models/developer.rb b/activerecord/test/models/developer.rb index 3627cfdd09..d2a5a7fc49 100644 --- a/activerecord/test/models/developer.rb +++ b/activerecord/test/models/developer.rb @@ -15,6 +15,8 @@ class Developer < ActiveRecord::Base accepts_nested_attributes_for :projects + has_and_belongs_to_many :shared_computers, class_name: "Computer" + has_and_belongs_to_many :projects_extended_by_name, -> { extending(DeveloperProjectsAssociationExtension) }, :class_name => "Project", diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index 539a0d2a49..720a127585 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -228,6 +228,11 @@ ActiveRecord::Schema.define do t.integer :extendedWarranty, null: false end + create_table :computers_developers, id: false, force: true do |t| + t.references :computer + t.references :developer + end + create_table :contracts, force: true do |t| t.integer :developer_id t.integer :company_id |