Skip to content

Commit

Permalink
Add deprecation warning for calling .create on has_many associations …
Browse files Browse the repository at this point in the history
…with an unsaved owner.

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


git-svn-id: http://svn-commit.rubyonrails.org/rails/branches/1-2-stable@7823 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information
NZKoz committed Oct 10, 2007
1 parent 3397839 commit a692432
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 9 deletions.
15 changes: 9 additions & 6 deletions activerecord/lib/active_record/associations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -994,12 +994,15 @@ def add_multiple_associated_save_callbacks(association_name)
after_callback = <<-end_eval
association = instance_variable_get("@#{association_name}")
if association.respond_to?(:loaded?) && association.loaded?
if @new_record_before_save
records_to_save = association
else
records_to_save = association.select { |record| record.new_record? }
end
records_to_save = if @new_record_before_save
association
elsif association.respond_to?(:loaded?) && association.loaded?
association.select { |record| record.new_record? }
else
[]
end
if !records_to_save.blank?
records_to_save.each { |record| association.send(:insert_record, record) }
association.send(:construct_sql) # reconstruct the SQL queries now that we know the owner's id
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,11 @@ def create(attributes = {})
attributes.collect { |attr| create(attr) }
else
record = build(attributes)
record.save unless @owner.new_record?
if @owner.new_record?
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")
else
record.save
end
record
end
end
Expand Down
12 changes: 12 additions & 0 deletions activerecord/test/associations_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ def test_save_on_parent_does_not_load_target
david.update_attribute(:created_at, Time.now)
assert !david.projects.loaded?
end

def test_save_on_parent_saves_children
developer = Developer.create :name => "Bryan", :salary => 50_000
assert_equal 1, developer.reload.audit_logs.size
end
end

class HasOneAssociationsTest < Test::Unit::TestCase
Expand Down Expand Up @@ -591,6 +596,13 @@ def test_adding_using_create
assert_equal 3, first_firm.plain_clients.size
end

def test_regular_create_on_has_many_when_parent_is_new_raises
assert_deprecated(/.build instead/) do
firm = Firm.new
firm.plain_clients.create :name=>"Whoever"
end
end

def test_adding_a_mismatch_class
assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << nil }
assert_raises(ActiveRecord::AssociationTypeMismatch) { companies(:first_firm).clients_of_firm << 1 }
Expand Down
5 changes: 5 additions & 0 deletions activerecord/test/fixtures/db_definitions/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,9 @@ def create_table(*args, &block)
create_table :lock_without_defaults_cust, :force => true do |t|
t.column :custom_lock_version, :integer
end

create_table :audit_logs, :force => true do |t|
t.column :message, :string, :null=>false
t.column :developer_id, :integer, :null=>false
end
end
10 changes: 10 additions & 0 deletions activerecord/test/fixtures/developer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,18 @@ def find_most_recent

has_and_belongs_to_many :special_projects, :join_table => 'developers_projects', :association_foreign_key => 'project_id'

has_many :audit_logs

validates_inclusion_of :salary, :in => 50000..200000
validates_length_of :name, :within => 3..20

before_create do |developer|
developer.audit_logs.build :message => "Computer created"
end
end

class AuditLog < ActiveRecord::Base
belongs_to :developer
end

DeveloperSalary = Struct.new(:amount)
Expand Down
4 changes: 2 additions & 2 deletions activerecord/test/validations_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,7 @@ def test_validates_size_of_association
t = Topic.new('title' => 'noreplies', 'content' => 'whatever')
assert !t.save
assert t.errors.on(:replies)
t.replies.create('title' => 'areply', 'content' => 'whateveragain')
t.replies.build('title' => 'areply', 'content' => 'whateveragain')
assert t.valid?
end

Expand Down Expand Up @@ -824,7 +824,7 @@ def test_validates_size_of_association_utf8
t = Topic.new('title' => 'あいうえお', 'content' => 'かきくけこ')
assert !t.save
assert t.errors.on(:replies)
t.replies.create('title' => 'あいうえお', 'content' => 'かきくけこ')
t.replies.build('title' => 'あいうえお', 'content' => 'かきくけこ')
assert t.valid?
end
end
Expand Down

0 comments on commit a692432

Please sign in to comment.