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
|
||||
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)
|
||||
_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
|
||||
end
|
||||
|
||||
def raw_write_attribute(attr_name, value) # :nodoc:
|
||||
private
|
||||
def write_attribute_without_type_cast(attr_name, value)
|
||||
name = attr_name.to_s
|
||||
@attributes.write_cast_value(name, value)
|
||||
value
|
||||
end
|
||||
|
||||
private
|
||||
# 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)
|
||||
|
Loading…
Reference in New Issue
Block a user