Skip to content

Commit

Permalink
While creating a new record using has_many create method default scop…
Browse files Browse the repository at this point in the history
…e of child should be respected.

author.posts.create should take into account default_scope
defined on post.

[#3939: state:resolved]

Signed-off-by: José Valim <jose.valim@gmail.com>
  • Loading branch information
Neeraj Singh authored and josevalim committed Aug 19, 2010
1 parent 43f44c1 commit 2e45542
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,12 @@ def add_record_to_target_with_callbacks(record)
def create_record(attrs)
attrs.update(@reflection.options[:conditions]) if @reflection.options[:conditions].is_a?(Hash)
ensure_owner_is_not_new
record = @reflection.klass.send(:with_scope, :create => construct_scope[:create]) do

_scope = self.construct_scope[:create]
csm = @reflection.klass.send(:current_scoped_methods)
options = (csm.blank? || !_scope.is_a?(Hash)) ? _scope : _scope.merge(csm.where_values_hash)

record = @reflection.klass.send(:with_scope, :create => options) do
@reflection.build_association(attrs)
end
if block_given?
Expand Down
11 changes: 7 additions & 4 deletions activerecord/lib/active_record/relation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -316,16 +316,19 @@ def to_sql
@to_sql ||= arel.to_sql
end

def scope_for_create
@scope_for_create ||= begin
@create_with_value || Hash[
@where_values.find_all { |w|
def where_values_hash
Hash[@where_values.find_all { |w|
w.respond_to?(:operator) && w.operator == :==
}.map { |where|
[where.operand1.name,
where.operand2.respond_to?(:value) ?
where.operand2.value : where.operand2]
}]
end

def scope_for_create
@scope_for_create ||= begin
@create_with_value || where_values_hash
end
end

Expand Down
19 changes: 19 additions & 0 deletions activerecord/test/cases/associations/has_many_associations_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
require 'models/tagging'
require 'models/invoice'
require 'models/line_item'
require 'models/car'
require 'models/bulb'

class HasManyAssociationsTestForCountWithFinderSql < ActiveRecord::TestCase
class Invoice < ActiveRecord::Base
Expand Down Expand Up @@ -47,6 +49,23 @@ def setup
Client.destroyed_client_ids.clear
end

def test_create_from_association_should_respect_default_scope
car = Car.create(:name => 'honda')
assert_equal 'honda', car.name

bulb = Bulb.create
assert_equal 'defaulty', bulb.name

bulb = car.bulbs.build
assert_equal 'defaulty', bulb.name

bulb = car.bulbs.create
assert_equal 'defaulty', bulb.name

bulb = car.bulbs.create(:name => 'exotic')
assert_equal 'exotic', bulb.name
end

def test_create_resets_cached_counters
person = Person.create!(:first_name => 'tenderlove')
post = Post.first
Expand Down
7 changes: 7 additions & 0 deletions activerecord/test/models/bulb.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Bulb < ActiveRecord::Base

default_scope :conditions => {:name => 'defaulty' }

This comment has been minimized.

Copy link
@jonathan

jonathan Aug 19, 2010

didn't the conditions hash go away with AR 3.0? should that be ":where => {:name => 'defaulty' }"

This comment has been minimized.

Copy link
@neerajsingh0101

neerajsingh0101 Aug 19, 2010

You are right. It has been deprecated. I should have used the syntax as you suggested.


belongs_to :car

end
1 change: 1 addition & 0 deletions activerecord/test/models/car.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
class Car < ActiveRecord::Base
has_many :bulbs
has_many :tyres
has_many :engines
has_many :wheels, :as => :wheelable
Expand Down
5 changes: 5 additions & 0 deletions activerecord/test/schema/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@ def create_table(*args, &block)
t.integer :car_id
end

create_table :bulbs, :force => true do |t|
t.integer :car_id
t.string :name
end

create_table :entrants, :force => true do |t|
t.string :name, :null => false
t.integer :course_id, :null => false
Expand Down

0 comments on commit 2e45542

Please sign in to comment.