Skip to content

Commit

Permalink
Fix ActiveRecord::Relation#create and #create! scope leaking to
Browse files Browse the repository at this point in the history
  • Loading branch information
guigs committed May 4, 2016
1 parent 40f68f7 commit 4189c65
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 4 deletions.
7 changes: 7 additions & 0 deletions activerecord/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
* Fix `ActiveRecord::Relation#create` and `#create!` scope leaking to
callbacks

Fixes #7391, #7853, #9894, #12305, #18952.

*Guilherme Goettems Schneider*

## Rails 5.0.0.beta4 (April 27, 2016) ##

* PostgreSQL: Support Expression Indexes and Operator Classes.
Expand Down
16 changes: 12 additions & 4 deletions activerecord/lib/active_record/relation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,12 @@ def new(*args, &block)
#
# users.create(name: nil) # validation on name
# # => #<User id: nil, name: nil, ...>
def create(*args, &block)
scoping { @klass.create(*args, &block) }
def create(args = nil, &block)
if args.is_a?(Array)
args.map { |attr| create(attr, &block) }
else
new(args, &block).tap(&:save)
end
end

# Similar to #create, but calls
Expand All @@ -156,8 +160,12 @@ def create(*args, &block)
#
# Expects arguments in the same format as
# {ActiveRecord::Base.create!}[rdoc-ref:Persistence::ClassMethods#create!].
def create!(*args, &block)
scoping { @klass.create!(*args, &block) }
def create!(args = nil, &block)
if args.is_a?(Array)
args.map { |attr| create!(attr, &block) }
else
new(args, &block).tap(&:save!)
end
end

def first_or_create(attributes = nil, &block) # :nodoc:
Expand Down
18 changes: 18 additions & 0 deletions activerecord/test/cases/relations_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1327,6 +1327,24 @@ def test_create_bang
assert_equal 'hen', hen.name
end

def test_create_with_callback
parrot = Bird.create!(name: 'parrot', color: 'green')

birds = Bird.all
hen = birds.where(name: 'hen').create do |bird|
bird.evangelist = true
bird.color = 'blue'
end

assert_kind_of Bird, hen
assert hen.persisted?
assert_equal 'hen', hen.name
assert_equal 'blue', hen.color

parrot.reload
assert_equal 'blue', parrot.color
end

def test_first_or_create
parrot = Bird.where(:color => 'green').first_or_create(:name => 'parrot')
assert_kind_of Bird, parrot
Expand Down
7 changes: 7 additions & 0 deletions activerecord/test/models/bird.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,11 @@ class Bird < ActiveRecord::Base
def cancel_save_callback_method
throw(:abort)
end

attr_accessor :evangelist
after_save :convert_all_to_my_color, if: :evangelist
def convert_all_to_my_color
self.class.update_all(color: color)
end

end

0 comments on commit 4189c65

Please sign in to comment.