Skip to content
This repository
Browse code

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
  • Loading branch information...
commit a692432d8a34cdebc0ea2b4a91fa79292654fe3f 1 parent 3397839
Michael Koziarski NZKoz authored
15 activerecord/lib/active_record/associations.rb
@@ -994,12 +994,15 @@ def add_multiple_associated_save_callbacks(association_name)
994 994 after_callback = <<-end_eval
995 995 association = instance_variable_get("@#{association_name}")
996 996
997   - if association.respond_to?(:loaded?) && association.loaded?
998   - if @new_record_before_save
999   - records_to_save = association
1000   - else
1001   - records_to_save = association.select { |record| record.new_record? }
1002   - end
  997 + records_to_save = if @new_record_before_save
  998 + association
  999 + elsif association.respond_to?(:loaded?) && association.loaded?
  1000 + association.select { |record| record.new_record? }
  1001 + else
  1002 + []
  1003 + end
  1004 +
  1005 + if !records_to_save.blank?
1003 1006 records_to_save.each { |record| association.send(:insert_record, record) }
1004 1007 association.send(:construct_sql) # reconstruct the SQL queries now that we know the owner's id
1005 1008 end
6 activerecord/lib/active_record/associations/association_collection.rb
@@ -91,7 +91,11 @@ def create(attributes = {})
91 91 attributes.collect { |attr| create(attr) }
92 92 else
93 93 record = build(attributes)
94   - record.save unless @owner.new_record?
  94 + if @owner.new_record?
  95 + 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")
  96 + else
  97 + record.save
  98 + end
95 99 record
96 100 end
97 101 end
12 activerecord/test/associations_test.rb
@@ -95,6 +95,11 @@ def test_save_on_parent_does_not_load_target
95 95 david.update_attribute(:created_at, Time.now)
96 96 assert !david.projects.loaded?
97 97 end
  98 +
  99 + def test_save_on_parent_saves_children
  100 + developer = Developer.create :name => "Bryan", :salary => 50_000
  101 + assert_equal 1, developer.reload.audit_logs.size
  102 + end
98 103 end
99 104
100 105 class HasOneAssociationsTest < Test::Unit::TestCase
@@ -591,6 +596,13 @@ def test_adding_using_create
591 596 assert_equal 3, first_firm.plain_clients.size
592 597 end
593 598
  599 + def test_regular_create_on_has_many_when_parent_is_new_raises
  600 + assert_deprecated(/.build instead/) do
  601 + firm = Firm.new
  602 + firm.plain_clients.create :name=>"Whoever"
  603 + end
  604 + end
  605 +
594 606 def test_adding_a_mismatch_class
595 607 assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << nil }
596 608 assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << 1 }
5 activerecord/test/fixtures/db_definitions/schema.rb
@@ -57,4 +57,9 @@ def create_table(*args, &block)
57 57 create_table :lock_without_defaults_cust, :force => true do |t|
58 58 t.column :custom_lock_version, :integer
59 59 end
  60 +
  61 + create_table :audit_logs, :force => true do |t|
  62 + t.column :message, :string, :null=>false
  63 + t.column :developer_id, :integer, :null=>false
  64 + end
60 65 end
10 activerecord/test/fixtures/developer.rb
@@ -31,8 +31,18 @@ def find_most_recent
31 31
32 32 has_and_belongs_to_many :special_projects, :join_table => 'developers_projects', :association_foreign_key => 'project_id'
33 33
  34 + has_many :audit_logs
  35 +
34 36 validates_inclusion_of :salary, :in => 50000..200000
35 37 validates_length_of :name, :within => 3..20
  38 +
  39 + before_create do |developer|
  40 + developer.audit_logs.build :message => "Computer created"
  41 + end
  42 +end
  43 +
  44 +class AuditLog < ActiveRecord::Base
  45 + belongs_to :developer
36 46 end
37 47
38 48 DeveloperSalary = Struct.new(:amount)
4 activerecord/test/validations_test.rb
@@ -631,7 +631,7 @@ def test_validates_size_of_association
631 631 t = Topic.new('title' => 'noreplies', 'content' => 'whatever')
632 632 assert !t.save
633 633 assert t.errors.on(:replies)
634   - t.replies.create('title' => 'areply', 'content' => 'whateveragain')
  634 + t.replies.build('title' => 'areply', 'content' => 'whateveragain')
635 635 assert t.valid?
636 636 end
637 637
@@ -824,7 +824,7 @@ def test_validates_size_of_association_utf8
824 824 t = Topic.new('title' => 'あいうえお', 'content' => 'かきくけこ')
825 825 assert !t.save
826 826 assert t.errors.on(:replies)
827   - t.replies.create('title' => 'あいうえお', 'content' => 'かきくけこ')
  827 + t.replies.build('title' => 'あいうえお', 'content' => 'かきくけこ')
828 828 assert t.valid?
829 829 end
830 830 end

0 comments on commit a692432

Please sign in to comment.
Something went wrong with that request. Please try again.