Skip to content

Commit

Permalink
Merge pull request #22300 from yui-knk/fix_21893
Browse files Browse the repository at this point in the history
Except keys of `build_record`'s argument from `create_scope` in initi…
  • Loading branch information
sgrif committed Nov 16, 2015
2 parents 0f78936 + 817c182 commit bde974f
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 5 deletions.
9 changes: 6 additions & 3 deletions activerecord/lib/active_record/associations/association.rb
Expand Up @@ -163,9 +163,12 @@ def marshal_load(data)
@reflection = @owner.class._reflect_on_association(reflection_name)
end

def initialize_attributes(record) #:nodoc:
def initialize_attributes(record, except_from_scope_attributes = nil) #:nodoc:
except_from_scope_attributes ||= {}
skip_assign = [reflection.foreign_key, reflection.type].compact
attributes = create_scope.except(*(record.changed - skip_assign))
assigned_keys = record.changed
assigned_keys += except_from_scope_attributes.keys.map(&:to_s)
attributes = create_scope.except(*(assigned_keys - skip_assign))
record.assign_attributes(attributes)
set_inverse_instance(record)
end
Expand Down Expand Up @@ -248,7 +251,7 @@ def stale_state

def build_record(attributes)
reflection.build_association(attributes) do |record|
initialize_attributes(record)
initialize_attributes(record, attributes)
end
end

Expand Down
Expand Up @@ -203,9 +203,22 @@ def test_create_from_association_should_respect_default_scope

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

def test_build_and_create_from_association_should_respect_passed_attributes_over_default_scope
car = Car.create(name: 'honda')

bulb = car.bulbs.build(name: 'exotic')
assert_equal 'exotic', bulb.name

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

bulb = car.awesome_bulbs.build(frickinawesome: false)
assert_equal false, bulb.frickinawesome

bulb = car.awesome_bulbs.create(frickinawesome: false)
assert_equal false, bulb.frickinawesome
end

def test_build_from_association_should_respect_scope
Expand Down
1 change: 1 addition & 0 deletions activerecord/test/models/bulb.rb
@@ -1,6 +1,7 @@
class Bulb < ActiveRecord::Base
default_scope { where(:name => 'defaulty') }
belongs_to :car, :touch => true
scope :awesome, -> { where(frickinawesome: true) }

attr_reader :scope_after_initialize, :attributes_after_initialize

Expand Down
1 change: 1 addition & 0 deletions activerecord/test/models/car.rb
Expand Up @@ -4,6 +4,7 @@ class Car < ActiveRecord::Base
has_many :funky_bulbs, class_name: 'FunkyBulb', dependent: :destroy
has_many :failed_bulbs, class_name: 'FailedBulb', dependent: :destroy
has_many :foo_bulbs, -> { where(:name => 'foo') }, :class_name => "Bulb"
has_many :awesome_bulbs, -> { awesome }, class_name: "Bulb"

has_one :bulb

Expand Down
2 changes: 1 addition & 1 deletion activerecord/test/schema/schema.rb
Expand Up @@ -114,7 +114,7 @@ def except(adapter_names_to_exclude)
create_table :bulbs, force: true do |t|
t.integer :car_id
t.string :name
t.boolean :frickinawesome
t.boolean :frickinawesome, default: false
t.string :color
end

Expand Down

0 comments on commit bde974f

Please sign in to comment.