Skip to content

Commit bde974f

Browse files
committed
Merge pull request rails#22300 from yui-knk/fix_21893
Except keys of `build_record`'s argument from `create_scope` in initi…
2 parents 0f78936 + 817c182 commit bde974f

File tree

5 files changed

+23
-5
lines changed

5 files changed

+23
-5
lines changed

activerecord/lib/active_record/associations/association.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,12 @@ def marshal_load(data)
163163
@reflection = @owner.class._reflect_on_association(reflection_name)
164164
end
165165

166-
def initialize_attributes(record) #:nodoc:
166+
def initialize_attributes(record, except_from_scope_attributes = nil) #:nodoc:
167+
except_from_scope_attributes ||= {}
167168
skip_assign = [reflection.foreign_key, reflection.type].compact
168-
attributes = create_scope.except(*(record.changed - skip_assign))
169+
assigned_keys = record.changed
170+
assigned_keys += except_from_scope_attributes.keys.map(&:to_s)
171+
attributes = create_scope.except(*(assigned_keys - skip_assign))
169172
record.assign_attributes(attributes)
170173
set_inverse_instance(record)
171174
end
@@ -248,7 +251,7 @@ def stale_state
248251

249252
def build_record(attributes)
250253
reflection.build_association(attributes) do |record|
251-
initialize_attributes(record)
254+
initialize_attributes(record, attributes)
252255
end
253256
end
254257

activerecord/test/cases/associations/has_many_associations_test.rb

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,22 @@ def test_create_from_association_should_respect_default_scope
203203

204204
bulb = car.bulbs.create
205205
assert_equal 'defaulty', bulb.name
206+
end
207+
208+
def test_build_and_create_from_association_should_respect_passed_attributes_over_default_scope
209+
car = Car.create(name: 'honda')
210+
211+
bulb = car.bulbs.build(name: 'exotic')
212+
assert_equal 'exotic', bulb.name
206213

207-
bulb = car.bulbs.create(:name => 'exotic')
214+
bulb = car.bulbs.create(name: 'exotic')
208215
assert_equal 'exotic', bulb.name
216+
217+
bulb = car.awesome_bulbs.build(frickinawesome: false)
218+
assert_equal false, bulb.frickinawesome
219+
220+
bulb = car.awesome_bulbs.create(frickinawesome: false)
221+
assert_equal false, bulb.frickinawesome
209222
end
210223

211224
def test_build_from_association_should_respect_scope

activerecord/test/models/bulb.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
class Bulb < ActiveRecord::Base
22
default_scope { where(:name => 'defaulty') }
33
belongs_to :car, :touch => true
4+
scope :awesome, -> { where(frickinawesome: true) }
45

56
attr_reader :scope_after_initialize, :attributes_after_initialize
67

activerecord/test/models/car.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ class Car < ActiveRecord::Base
44
has_many :funky_bulbs, class_name: 'FunkyBulb', dependent: :destroy
55
has_many :failed_bulbs, class_name: 'FailedBulb', dependent: :destroy
66
has_many :foo_bulbs, -> { where(:name => 'foo') }, :class_name => "Bulb"
7+
has_many :awesome_bulbs, -> { awesome }, class_name: "Bulb"
78

89
has_one :bulb
910

activerecord/test/schema/schema.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def except(adapter_names_to_exclude)
114114
create_table :bulbs, force: true do |t|
115115
t.integer :car_id
116116
t.string :name
117-
t.boolean :frickinawesome
117+
t.boolean :frickinawesome, default: false
118118
t.string :color
119119
end
120120

0 commit comments

Comments
 (0)