public
Fork of rails/rails
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/josh/rails.git
Add deprecation warning for calling .create on has_many associations with 
an unsaved owner.

Fix regression introduced by [7076] by restoring 1.2.3 behaviour for 
saving associated records [Bryan Helmkamp].  References #8713


git-svn-id: 
http://svn-commit.rubyonrails.org/rails/branches/1-2-stable@7823 
5ecf4fe2-1ee6-0310-87b1-e25e094e27de
NZKoz (author)
Tue Oct 09 22:42:52 -0700 2007
commit  a692432d8a34cdebc0ea2b4a91fa79292654fe3f
tree    b72d0288d91c99ee10c55556d89e0f6ee50c0c78
parent  3397839ac7487ef66091d0781b77b5a69a3d7f69
...
994
995
996
997
998
999
1000
1001
1002
 
 
 
 
 
 
 
 
 
1003
1004
1005
...
994
995
996
 
 
 
 
 
 
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
0
@@ -994,12 +994,15 @@ module ActiveRecord
0
           after_callback = <<-end_eval
0
             association = instance_variable_get("@#{association_name}")
0
 
0
- if association.respond_to?(:loaded?) && association.loaded?
0
- if @new_record_before_save
0
- records_to_save = association
0
- else
0
- records_to_save = association.select { |record| record.new_record? }
0
- end
0
+ records_to_save = if @new_record_before_save
0
+ association
0
+ elsif association.respond_to?(:loaded?) && association.loaded?
0
+ association.select { |record| record.new_record? }
0
+ else
0
+ []
0
+ end
0
+
0
+ if !records_to_save.blank?
0
               records_to_save.each { |record| association.send(:insert_record, record) }
0
               association.send(:construct_sql) # reconstruct the SQL queries now that we know the owner's id
0
             end
...
91
92
93
94
 
 
 
 
 
95
96
97
...
91
92
93
 
94
95
96
97
98
99
100
101
0
@@ -91,7 +91,11 @@ module ActiveRecord
0
           attributes.collect { |attr| create(attr) }
0
         else
0
           record = build(attributes)
0
- record.save unless @owner.new_record?
0
+ if @owner.new_record?
0
+ ActiveSupport::Deprecation.warn("Calling .create on a has_many association without saving its owner will not work in rails 2.0, you probably want .build instead")
0
+ else
0
+ record.save
0
+ end
0
           record
0
         end
0
       end
...
95
96
97
 
 
 
 
 
98
99
100
...
591
592
593
 
 
 
 
 
 
 
594
595
596
...
95
96
97
98
99
100
101
102
103
104
105
...
596
597
598
599
600
601
602
603
604
605
606
607
608
0
@@ -95,6 +95,11 @@ class AssociationProxyTest < Test::Unit::TestCase
0
     david.update_attribute(:created_at, Time.now)
0
     assert !david.projects.loaded?
0
   end
0
+
0
+ def test_save_on_parent_saves_children
0
+ developer = Developer.create :name => "Bryan", :salary => 50_000
0
+ assert_equal 1, developer.reload.audit_logs.size
0
+ end
0
 end
0
 
0
 class HasOneAssociationsTest < Test::Unit::TestCase
0
@@ -591,6 +596,13 @@ class HasManyAssociationsTest < Test::Unit::TestCase
0
     assert_equal 3, first_firm.plain_clients.size
0
   end
0
   
0
+ def test_regular_create_on_has_many_when_parent_is_new_raises
0
+ assert_deprecated(/.build instead/) do
0
+ firm = Firm.new
0
+ firm.plain_clients.create :name=>"Whoever"
0
+ end
0
+ end
0
+
0
   def test_adding_a_mismatch_class
0
     assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << nil }
0
     assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << 1 }
...
57
58
59
 
 
 
 
 
60
...
57
58
59
60
61
62
63
64
65
0
@@ -57,4 +57,9 @@ ActiveRecord::Schema.define do
0
   create_table :lock_without_defaults_cust, :force => true do |t|
0
     t.column :custom_lock_version, :integer
0
   end
0
+
0
+ create_table :audit_logs, :force => true do |t|
0
+ t.column :message, :string, :null=>false
0
+ t.column :developer_id, :integer, :null=>false
0
+ end
0
 end
...
31
32
33
 
 
34
35
 
 
 
 
 
 
 
 
36
37
38
...
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
0
@@ -31,8 +31,18 @@ class Developer < ActiveRecord::Base
0
 
0
   has_and_belongs_to_many :special_projects, :join_table => 'developers_projects', :association_foreign_key => 'project_id'
0
 
0
+ has_many :audit_logs
0
+
0
   validates_inclusion_of :salary, :in => 50000..200000
0
   validates_length_of :name, :within => 3..20
0
+
0
+ before_create do |developer|
0
+ developer.audit_logs.build :message => "Computer created"
0
+ end
0
+end
0
+
0
+class AuditLog < ActiveRecord::Base
0
+ belongs_to :developer
0
 end
0
 
0
 DeveloperSalary = Struct.new(:amount)
...
631
632
633
634
 
635
636
637
...
824
825
826
827
 
828
829
830
...
631
632
633
 
634
635
636
637
...
824
825
826
 
827
828
829
830
0
@@ -631,7 +631,7 @@ class ValidationsTest < Test::Unit::TestCase
0
     t = Topic.new('title' => 'noreplies', 'content' => 'whatever')
0
     assert !t.save
0
     assert t.errors.on(:replies)
0
- t.replies.create('title' => 'areply', 'content' => 'whateveragain')
0
+ t.replies.build('title' => 'areply', 'content' => 'whateveragain')
0
     assert t.valid?
0
   end
0
 
0
@@ -824,7 +824,7 @@ class ValidationsTest < Test::Unit::TestCase
0
       t = Topic.new('title' => 'あいうえお', 'content' => 'かきくけこ')
0
       assert !t.save
0
       assert t.errors.on(:replies)
0
- t.replies.create('title' => 'あいうえお', 'content' => 'かきくけこ')
0
+ t.replies.build('title' => 'あいうえお', 'content' => 'かきくけこ')
0
       assert t.valid?
0
     end
0
   end

Comments

    No one has commented yet.