mirror of
https://github.com/github/rails.git
synced 2026-01-29 16:28:09 -05:00
Fix the has_and_belongs_to_many #create doesn't populate the join for new records. Closes #3692 [josh@hasmanythrough.com]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4379 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
*SVN*
|
||||
|
||||
* Fix the has_and_belongs_to_many #create doesn't populate the join for new records. Closes #3692 [josh@hasmanythrough.com]
|
||||
|
||||
* Provide Association Extensions access to the instance that the association is being accessed from.
|
||||
Closes #4433 [josh@hasmanythrough.com]
|
||||
|
||||
|
||||
@@ -763,6 +763,10 @@ module ActiveRecord
|
||||
# * <tt>collection.size</tt> - returns the number of associated objects.
|
||||
# * <tt>collection.find(id)</tt> - finds an associated object responding to the +id+ and that
|
||||
# meets the condition that it has to be associated with this object.
|
||||
# * <tt>collection.build(attributes = {})</tt> - returns a new object of the collection type that has been instantiated
|
||||
# with +attributes+ and linked to this object through the join table but has not yet been saved.
|
||||
# * <tt>collection.create(attributes = {})</tt> - returns a new object of the collection type that has been instantiated
|
||||
# with +attributes+ and linked to this object through the join table and that has already been saved (if it passed the validation).
|
||||
#
|
||||
# Example: An Developer class declares <tt>has_and_belongs_to_many :projects</tt>, which will add:
|
||||
# * <tt>Developer#projects</tt>
|
||||
@@ -775,6 +779,8 @@ module ActiveRecord
|
||||
# * <tt>Developer#projects.empty?</tt>
|
||||
# * <tt>Developer#projects.size</tt>
|
||||
# * <tt>Developer#projects.find(id)</tt>
|
||||
# * <tt>Developer#projects.build</tt> (similar to <tt>Project.new("project_id" => id)</tt>)
|
||||
# * <tt>Developer#projects.create</tt> (similar to <tt>c = Project.new("project_id" => id); c.save; c</tt>)
|
||||
# The declaration may include an options hash to specialize the behavior of the association.
|
||||
#
|
||||
# Options are:
|
||||
|
||||
@@ -13,6 +13,17 @@ module ActiveRecord
|
||||
record
|
||||
end
|
||||
|
||||
def create(attributes = {})
|
||||
# Can't use Base.create since the foreign key may be a protected attribute.
|
||||
if attributes.is_a?(Array)
|
||||
attributes.collect { |attr| create(attr) }
|
||||
else
|
||||
record = build(attributes)
|
||||
insert_record(record) unless @owner.new_record?
|
||||
record
|
||||
end
|
||||
end
|
||||
|
||||
def find_first
|
||||
load_target.first
|
||||
end
|
||||
|
||||
@@ -1354,6 +1354,20 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
||||
devel.save
|
||||
assert !proj.new_record?
|
||||
assert_equal devel.projects.last, proj
|
||||
assert_equal Developer.find(1).projects.last, proj # prove join table is updated
|
||||
end
|
||||
|
||||
def test_build_by_new_record
|
||||
devel = Developer.new(:name => "Marcel", :salary => 75000)
|
||||
proj1 = devel.projects.build(:name => "Make bed")
|
||||
proj2 = devel.projects.build(:name => "Lie in it")
|
||||
assert_equal devel.projects.last, proj2
|
||||
assert proj2.new_record?
|
||||
devel.save
|
||||
assert !devel.new_record?
|
||||
assert !proj2.new_record?
|
||||
assert_equal devel.projects.last, proj2
|
||||
assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
|
||||
end
|
||||
|
||||
def test_create
|
||||
@@ -1361,6 +1375,20 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
||||
proj = devel.projects.create("name" => "Projekt")
|
||||
assert_equal devel.projects.last, proj
|
||||
assert !proj.new_record?
|
||||
assert_equal Developer.find(1).projects.last, proj # prove join table is updated
|
||||
end
|
||||
|
||||
def test_create_by_new_record
|
||||
devel = Developer.new(:name => "Marcel", :salary => 75000)
|
||||
proj1 = devel.projects.create(:name => "Make bed")
|
||||
proj2 = devel.projects.create(:name => "Lie in it")
|
||||
assert_equal devel.projects.last, proj2
|
||||
assert proj2.new_record?
|
||||
devel.save
|
||||
assert !devel.new_record?
|
||||
assert !proj2.new_record?
|
||||
assert_equal devel.projects.last, proj2
|
||||
assert_equal Developer.find_by_name("Marcel").projects.last, proj2 # prove join table is updated
|
||||
end
|
||||
|
||||
def test_uniq_after_the_fact
|
||||
|
||||
Reference in New Issue
Block a user