提交 5c17e349 编写于 作者: M Matthew Draper 提交者: GitHub

Merge pull request #29495 from eugeneius/_write_attribute

Improve the performance of writing attributes
......@@ -80,7 +80,7 @@ def clear_changes_information
clear_mutation_trackers
end
def raw_write_attribute(attr_name, *)
def write_attribute_without_type_cast(attr_name, *)
result = super
clear_attribute_change(attr_name)
result
......
......@@ -21,7 +21,7 @@ def id
# Sets the primary key value.
def id=(value)
sync_with_transaction_state
write_attribute(self.class.primary_key, value) if self.class.primary_key
_write_attribute(self.class.primary_key, value) if self.class.primary_key
end
# Queries the primary key value.
......
......@@ -17,7 +17,7 @@ def define_method_attribute=(name)
generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
def __temp__#{safe_name}=(value)
name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name}
write_attribute(name, value)
_write_attribute(name, value)
end
alias_method #{(name + '=').inspect}, :__temp__#{safe_name}=
undef_method :__temp__#{safe_name}=
......@@ -36,20 +36,26 @@ def write_attribute(attr_name, value)
end
name = self.class.primary_key if name == "id".freeze && self.class.primary_key
@attributes.write_from_user(name, value)
value
_write_attribute(name, value)
end
def raw_write_attribute(attr_name, value) # :nodoc:
name = attr_name.to_s
@attributes.write_cast_value(name, value)
# This method exists to avoid the expensive primary_key check internally, without
# breaking compatibility with the write_attribute API
def _write_attribute(attr_name, value) # :nodoc:
@attributes.write_from_user(attr_name.to_s, value)
value
end
private
def write_attribute_without_type_cast(attr_name, value)
name = attr_name.to_s
@attributes.write_cast_value(name, value)
value
end
# Handle *= for method_missing.
def attribute=(attribute_name, value)
write_attribute(attribute_name, value)
_write_attribute(attribute_name, value)
end
end
end
......
......@@ -245,7 +245,7 @@ def initialize_internals_callback
def ensure_proper_type
klass = self.class
if klass.finder_needs_type_condition?
write_attribute(klass.inheritance_column, klass.sti_name)
_write_attribute(klass.inheritance_column, klass.sti_name)
end
end
end
......
......@@ -333,7 +333,7 @@ def update_columns(attributes)
updated_count = self.class.unscoped.where(self.class.primary_key => id).update_all(attributes)
attributes.each do |k, v|
raw_write_attribute(k, v)
write_attribute_without_type_cast(k, v)
end
updated_count == 1
......
......@@ -86,7 +86,7 @@ def _create_record
all_timestamp_attributes_in_model.each do |column|
if !attribute_present?(column)
write_attribute(column, current_time)
_write_attribute(column, current_time)
end
end
end
......@@ -100,7 +100,7 @@ def _update_record(*args, touch: true, **options)
timestamp_attributes_for_update_in_model.each do |column|
next if will_save_change_to_attribute?(column)
write_attribute(column, current_time)
_write_attribute(column, current_time)
end
end
super(*args)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册