Merge pull request #29495 from eugeneius/_write_attribute
Improve the performance of writing attributes
This commit is contained in:
commit
5c17e34946
@ -80,7 +80,7 @@ def clear_changes_information
|
|||||||
clear_mutation_trackers
|
clear_mutation_trackers
|
||||||
end
|
end
|
||||||
|
|
||||||
def raw_write_attribute(attr_name, *)
|
def write_attribute_without_type_cast(attr_name, *)
|
||||||
result = super
|
result = super
|
||||||
clear_attribute_change(attr_name)
|
clear_attribute_change(attr_name)
|
||||||
result
|
result
|
||||||
|
@ -21,7 +21,7 @@ def id
|
|||||||
# Sets the primary key value.
|
# Sets the primary key value.
|
||||||
def id=(value)
|
def id=(value)
|
||||||
sync_with_transaction_state
|
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
|
end
|
||||||
|
|
||||||
# Queries the primary key value.
|
# Queries the primary key value.
|
||||||
|
@ -17,7 +17,7 @@ def define_method_attribute=(name)
|
|||||||
generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
|
generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
|
||||||
def __temp__#{safe_name}=(value)
|
def __temp__#{safe_name}=(value)
|
||||||
name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name}
|
name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name}
|
||||||
write_attribute(name, value)
|
_write_attribute(name, value)
|
||||||
end
|
end
|
||||||
alias_method #{(name + '=').inspect}, :__temp__#{safe_name}=
|
alias_method #{(name + '=').inspect}, :__temp__#{safe_name}=
|
||||||
undef_method :__temp__#{safe_name}=
|
undef_method :__temp__#{safe_name}=
|
||||||
@ -36,20 +36,26 @@ def write_attribute(attr_name, value)
|
|||||||
end
|
end
|
||||||
|
|
||||||
name = self.class.primary_key if name == "id".freeze && self.class.primary_key
|
name = self.class.primary_key if name == "id".freeze && self.class.primary_key
|
||||||
@attributes.write_from_user(name, value)
|
_write_attribute(name, value)
|
||||||
|
end
|
||||||
|
|
||||||
|
# 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
|
value
|
||||||
end
|
end
|
||||||
|
|
||||||
def raw_write_attribute(attr_name, value) # :nodoc:
|
private
|
||||||
|
def write_attribute_without_type_cast(attr_name, value)
|
||||||
name = attr_name.to_s
|
name = attr_name.to_s
|
||||||
@attributes.write_cast_value(name, value)
|
@attributes.write_cast_value(name, value)
|
||||||
value
|
value
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
# Handle *= for method_missing.
|
# Handle *= for method_missing.
|
||||||
def attribute=(attribute_name, value)
|
def attribute=(attribute_name, value)
|
||||||
write_attribute(attribute_name, value)
|
_write_attribute(attribute_name, value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -245,7 +245,7 @@ def initialize_internals_callback
|
|||||||
def ensure_proper_type
|
def ensure_proper_type
|
||||||
klass = self.class
|
klass = self.class
|
||||||
if klass.finder_needs_type_condition?
|
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
|
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)
|
updated_count = self.class.unscoped.where(self.class.primary_key => id).update_all(attributes)
|
||||||
|
|
||||||
attributes.each do |k, v|
|
attributes.each do |k, v|
|
||||||
raw_write_attribute(k, v)
|
write_attribute_without_type_cast(k, v)
|
||||||
end
|
end
|
||||||
|
|
||||||
updated_count == 1
|
updated_count == 1
|
||||||
|
@ -86,7 +86,7 @@ def _create_record
|
|||||||
|
|
||||||
all_timestamp_attributes_in_model.each do |column|
|
all_timestamp_attributes_in_model.each do |column|
|
||||||
if !attribute_present?(column)
|
if !attribute_present?(column)
|
||||||
write_attribute(column, current_time)
|
_write_attribute(column, current_time)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -100,7 +100,7 @@ def _update_record(*args, touch: true, **options)
|
|||||||
|
|
||||||
timestamp_attributes_for_update_in_model.each do |column|
|
timestamp_attributes_for_update_in_model.each do |column|
|
||||||
next if will_save_change_to_attribute?(column)
|
next if will_save_change_to_attribute?(column)
|
||||||
write_attribute(column, current_time)
|
_write_attribute(column, current_time)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
super(*args)
|
super(*args)
|
||||||
|
Loading…
Reference in New Issue
Block a user