Ticket #3005: association-duplicate-names-prevent-v3.patch
| File association-duplicate-names-prevent-v3.patch, 5.4 kB (added by François Beausoleil <francois.beausoleil@gmail.com>, 3 years ago) |
|---|
-
activerecord/test/associations_test.rb
old new 258 258 assert_equal a, firm.account 259 259 assert_equal a, firm.account(true) 260 260 end 261 262 def test_prevent_naming_association_with_existing_name 263 firm = Firm.new 264 assert_raise ActiveRecord::Reflection::ReflectionNameAlreadyTaken do 265 class << firm 266 has_one :quote 267 end 268 end 269 end 261 270 end 262 271 263 272 … … 741 750 assert_equal 2, firm.clients.length 742 751 assert firm.clients.include?(companies(:second_client)) 743 752 end 753 754 def test_prevent_naming_association_with_existing_name 755 firm = Firm.new 756 assert_raise ActiveRecord::Reflection::ReflectionNameAlreadyTaken do 757 class << firm 758 has_many :columns 759 end 760 end 761 end 744 762 end 745 763 746 764 class BelongsToAssociationsTest < Test::Unit::TestCase … … 997 1015 # the author id of the post should be the id we set 998 1016 assert_equal post.author_id, author2.id 999 1017 end 1000 1018 1019 def test_prevent_naming_association_with_existing_name 1020 firm = Firm.new 1021 assert_raise ActiveRecord::Reflection::ReflectionNameAlreadyTaken do 1022 class << firm 1023 belongs_to :quote 1024 end 1025 end 1026 end 1001 1027 end 1002 1028 1003 1029 … … 1417 1443 AND developer_id = #{developer.id} 1418 1444 end_sql 1419 1445 end 1446 1447 def test_prevent_naming_association_with_existing_name 1448 firm = Firm.new 1449 assert_raise ActiveRecord::Reflection::ReflectionNameAlreadyTaken do 1450 class << firm 1451 has_and_belongs_to_many :columns 1452 end 1453 end 1454 end 1420 1455 end -
activerecord/test/aggregations_test.rb
old new 63 63 def test_gps_inequality 64 64 assert GpsLocation.new('39x110') != GpsLocation.new('39x111') 65 65 end 66 67 def test_prevent_naming_aggregation_with_existing_name 68 assert_raise ActiveRecord::Reflection::ReflectionNameAlreadyTaken do 69 class << customers(:david) 70 composed_of :base_class, :class_name => 'Money' 71 end 72 end 73 end 66 74 end -
activerecord/lib/active_record/reflection.rb
old new 1 1 module ActiveRecord 2 2 module Reflection # :nodoc: 3 class ReflectionNameAlreadyTaken < ActiveRecord::ConfigurationError; end 4 3 5 def self.included(base) 4 6 base.extend(ClassMethods) 5 7 end … … 11 13 # You can find the interface for the AggregateReflection and AssociationReflection classes in the abstract MacroReflection class. 12 14 module ClassMethods 13 15 def create_reflection(macro, name, options, active_record) 16 guard_against_already_used_reflection_name(name, active_record) 14 17 case macro 15 18 when :has_many, :belongs_to, :has_one, :has_and_belongs_to_many 16 19 reflection = AssociationReflection.new(macro, name, options, active_record) … … 48 51 def reflect_on_association(association) 49 52 reflections[association].is_a?(AssociationReflection) ? reflections[association] : nil 50 53 end 54 55 protected 56 def guard_against_already_used_reflection_name(name, active_record) 57 methods = active_record.instance_methods 58 methods += ActiveRecord::Base.methods 59 methods -= Object.methods 60 methods.uniq! 61 methods -= %w(name type) 62 return unless methods.include?(name.to_s) 63 64 # Raise the exception and say WHERE we found the method (very helpful) 65 raise_reflection_already_taken(active_record, name, :instance_methods) 66 raise_reflection_already_taken(ActiveRecord::Base, name, :methods) 67 68 # We couldn't find it ! Wow, that's bad. Real bad... 69 raise ReflectionNameAlreadyTaken, "`#{name}' is the name of an existing method in #{active_record.name} (but I can't find where this method is already defined !). You will have to rename your association." 70 end 71 72 def raise_reflection_already_taken(klass, association_name, target) 73 loop do 74 methods = klass.send(target) 75 methods -= klass.superclass.send(target) if klass.superclass 76 raise ReflectionNameAlreadyTaken, "`#{association_name}' is the name of an existing method in #{active_record.name} (class #{klass.name} [#{target}]). You will have to rename your association." if methods.include?(association_name) 77 return if klass == Object 78 klass = klass.superclass 79 end 80 end 51 81 end 52 82 53 83 -
activerecord/lib/active_record/aggregations.rb
old new 131 131 class_name = options[:class_name] || name_to_class_name(name) 132 132 mapping = options[:mapping] || [ name, name ] 133 133 134 create_reflection(:composed_of, part_id, options, self) 135 134 136 reader_method(name, class_name, mapping) 135 137 writer_method(name, class_name, mapping) 136 137 create_reflection(:composed_of, part_id, options, self)138 138 end 139 139 140 140 private