public
Fork of rails/rails
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/josh/rails.git
Fix has_many :through delete with custom foreign keys. References #6466.

git-svn-id: 
http://svn-commit.rubyonrails.org/rails/branches/1-2-stable@8042 
5ecf4fe2-1ee6-0310-87b1-e25e094e27de
jeremy (author)
Sat Oct 27 11:49:52 -0700 2007
commit  1117d73787c13f61b338cb54bf7992f9c6d2a05d
tree    0f9a970110dc21f986fff9a76d6601d67d2c080c
parent  5285270dde50cd83239b70a23139319dd8d9e302
...
1
2
 
 
3
4
5
...
1
2
3
4
5
6
7
0
@@ -1,5 +1,7 @@
0
 *SVN*
0
 
0
+* Fix has_many :through delete with custom foreign keys. #6466 [naffis]
0
+
0
 * Fix regression where the association would not construct new finder SQL on save causing bogus queries for "WHERE owner_id = NULL" even after owner was saved. #8713 [Bryan Helmkamp]
0
 
0
 
...
50
51
52
 
 
 
 
 
 
53
54
55
...
50
51
52
53
54
55
56
57
58
59
60
61
0
@@ -50,6 +50,12 @@ module ActiveRecord
0
     end
0
   end
0
 
0
+ class HasManyThroughCantDissociateNewRecords < ActiveRecordError #:nodoc:
0
+ def initialize(owner, reflection)
0
+ super("Cannot dissociate new records through '#{owner.class.name}##{reflection.name}' on '#{reflection.source_reflection.class_name rescue nil}##{reflection.source_reflection.name rescue nil}'. Both records must have an id in order to delete the has_many :through record associating them.")
0
+ end
0
+ end
0
+
0
   class EagerLoadPolymorphicError < ActiveRecordError #:nodoc:
0
     def initialize(reflection)
0
       super("Can not eagerly load the polymorphic association #{reflection.name.inspect}")
...
71
72
73
74
75
76
77
78
79
 
 
80
81
82
83
84
 
 
 
 
 
 
 
 
 
 
 
85
86
87
 
 
88
89
90
...
71
72
73
 
 
 
74
 
 
75
76
77
 
 
 
 
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
0
@@ -71,20 +71,26 @@ module ActiveRecord
0
 
0
       # Remove +records+ from this association. Does not destroy +records+.
0
       def delete(*records)
0
- records = flatten_deeper(records)
0
- records.each { |associate| raise_on_type_mismatch(associate) }
0
- records.reject! { |associate| @target.delete(associate) if associate.new_record? }
0
         return if records.empty?
0
-
0
- @delete_join_finder ||= "find_all_by_#{@reflection.source_reflection.association_foreign_key}"
0
+ records.each { |associate| raise_on_type_mismatch(associate) }
0
+
0
         through = @reflection.through_reflection
0
- through.klass.transaction do
0
- records.each do |associate|
0
- joins = @owner.send(through.name).send(@delete_join_finder, associate.id)
0
- @owner.send(through.name).delete(joins)
0
+ raise ActiveRecord::HasManyThroughCantDissociateNewRecords.new(@owner, through) if @owner.new_record?
0
+
0
+ load_target
0
+
0
+ klass = through.klass
0
+ klass.transaction do
0
+ flatten_deeper(records).each do |associate|
0
+ raise_on_type_mismatch(associate)
0
+ raise ActiveRecord::HasManyThroughCantDissociateNewRecords.new(@owner, through) unless associate.respond_to?(:new_record?) && !associate.new_record?
0
+
0
+ @owner.send(@reflection.through_reflection.name).proxy_target.delete(klass.delete_all(construct_join_attributes(associate)))
0
             @target.delete(associate)
0
           end
0
         end
0
+
0
+ self
0
       end
0
 
0
       def build(attrs = nil)
...
8
9
10
 
 
11
12
13
14
 
15
16
17
...
450
451
452
453
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
454
455
456
...
8
9
10
11
12
13
14
15
 
16
17
18
19
...
452
453
454
 
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
0
@@ -8,10 +8,12 @@ require 'fixtures/category'
0
 require 'fixtures/categorization'
0
 require 'fixtures/vertex'
0
 require 'fixtures/edge'
0
+require 'fixtures/book'
0
+require 'fixtures/citation'
0
 
0
 class AssociationsJoinModelTest < Test::Unit::TestCase
0
   self.use_transactional_fixtures = false
0
- fixtures :posts, :authors, :categories, :categorizations, :comments, :tags, :taggings, :author_favorites, :vertices
0
+ fixtures :posts, :authors, :categories, :categorizations, :comments, :tags, :taggings, :author_favorites, :vertices, :books
0
 
0
   def test_has_many
0
     assert authors(:david).categories.include?(categories(:general))
0
@@ -450,7 +452,21 @@ class AssociationsJoinModelTest < Test::Unit::TestCase
0
     tags = posts(:thinking).tags
0
     assert_equal tags, posts(:thinking).tags.push(tags(:general))
0
   end
0
-
0
+
0
+ def test_delete_associate_when_deleting_from_has_many_through_with_non_standard_id
0
+ count = books(:awdr).references.count
0
+ references_before = books(:awdr).references
0
+ book = Book.create!(:name => 'Getting Real')
0
+ book_awdr = books(:awdr)
0
+ book_awdr.references << book
0
+ assert_equal(count + 1, book_awdr.references(true).size)
0
+
0
+ assert_nothing_raised { book_awdr.references.delete(book) }
0
+ assert_equal(count, book_awdr.references.size)
0
+ assert_equal(count, book_awdr.references(true).size)
0
+ assert_equal(references_before.sort, book_awdr.references.sort)
0
+ end
0
+
0
   def test_delete_associate_when_deleting_from_has_many_through
0
     count = posts(:thinking).tags.count
0
     tags_before = posts(:thinking).tags
...
62
63
64
 
 
 
 
 
 
 
 
 
65
...
62
63
64
65
66
67
68
69
70
71
72
73
74
0
@@ -62,4 +62,13 @@ ActiveRecord::Schema.define do
0
     t.column :message, :string, :null=>false
0
     t.column :developer_id, :integer, :null=>false
0
   end
0
+
0
+ create_table :books, :force => true do |t|
0
+ t.column :name, :string
0
+ end
0
+
0
+ create_table :citations, :force => true do |t|
0
+ t.column :book1_id, :integer
0
+ t.column :book2_id, :integer
0
+ end
0
 end

Comments

    No one has commented yet.