From 538b19c47eadc43c923527d7c0a4caa66b5cda7e Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Tue, 11 Sep 2018 23:05:40 +0900 Subject: Refactor object creation from relation to avoid pushing scope attributes Pushing scope attributes was added at d4007d5 for fixing inheritance object creation. But it was not a better fix, since we could just pull that on demand in `Inheritance` module. --- activerecord/lib/active_record/inheritance.rb | 4 ++++ activerecord/lib/active_record/relation.rb | 27 +++------------------------ 2 files changed, 7 insertions(+), 24 deletions(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/inheritance.rb b/activerecord/lib/active_record/inheritance.rb index 6891c575c7..b25057acda 100644 --- a/activerecord/lib/active_record/inheritance.rb +++ b/activerecord/lib/active_record/inheritance.rb @@ -55,6 +55,10 @@ module ActiveRecord if has_attribute?(inheritance_column) subclass = subclass_from_attributes(attributes) + if subclass.nil? && scope_attributes = current_scope&.scope_for_create + subclass = subclass_from_attributes(scope_attributes) + end + if subclass.nil? && base_class? subclass = subclass_from_attributes(column_defaults) end diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 36e72dcd8a..86e5d14c81 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -62,7 +62,7 @@ module ActiveRecord # user = users.new { |user| user.name = 'Oscar' } # user.name # => Oscar def new(attributes = nil, &block) - scoping { klass.new(values_for_create(attributes), &block) } + scoping { klass.new(attributes, &block) } end alias build new @@ -87,11 +87,7 @@ module ActiveRecord # users.create(name: nil) # validation on name # # => # def create(attributes = nil, &block) - if attributes.is_a?(Array) - attributes.collect { |attr| create(attr, &block) } - else - scoping { klass.create(values_for_create(attributes), &block) } - end + scoping { klass.create(attributes, &block) } end # Similar to #create, but calls @@ -101,11 +97,7 @@ module ActiveRecord # Expects arguments in the same format as # {ActiveRecord::Base.create!}[rdoc-ref:Persistence::ClassMethods#create!]. def create!(attributes = nil, &block) - if attributes.is_a?(Array) - attributes.collect { |attr| create!(attr, &block) } - else - scoping { klass.create!(values_for_create(attributes), &block) } - end + scoping { klass.create!(attributes, &block) } end def first_or_create(attributes = nil, &block) # :nodoc: @@ -703,18 +695,5 @@ module ActiveRecord # ignore raw_sql_ that is used by Oracle adapter as alias for limit/offset subqueries string.scan(/([a-zA-Z_][.\w]+).?\./).flatten.map(&:downcase).uniq - ["raw_sql_"] end - - def values_for_create(attributes = nil) - result = attributes ? where_values_hash.merge!(attributes) : where_values_hash - - # NOTE: if there are same keys in both create_with and result, create_with should be used. - # This is to make sure nested attributes don't get passed to the klass.new, - # while keeping the precedence of the duplicate keys in create_with. - create_with_value.stringify_keys.each do |k, v| - result[k] = v if result.key?(k) - end - - result - end end end -- cgit v1.2.3