Improve the performance of reading belongs_to associations

`ActiveRecord::Base#[]` has overhead that was introduced in 4.2. The
`foo["id"]` working with PKs other than ID isn't really a case that we
want to support publicly, but deprecating was painful enough that we
avoid it. `_read_attribute` was introduced as the faster alternative for
use internally. By using that, we can save a lot of overhead. We also
save some overhead by reading the attribute one fewer times in
`stale_state`.

Fixes #18151
This commit is contained in:
Sean Griffin 2014-12-22 16:38:38 -07:00
parent fb160f6e7d
commit be2b98b4ae

@ -73,11 +73,11 @@ def increment_counter(counter_cache_name)
# Checks whether record is different to the current target, without loading it # Checks whether record is different to the current target, without loading it
def different_target?(record) def different_target?(record)
record.id != owner[reflection.foreign_key] record.id != owner._read_attribute(reflection.foreign_key)
end end
def replace_keys(record) def replace_keys(record)
owner[reflection.foreign_key] = record[reflection.association_primary_key(record.class)] owner[reflection.foreign_key] = record._read_attribute(reflection.association_primary_key(record.class))
end end
def remove_keys def remove_keys
@ -85,7 +85,7 @@ def remove_keys
end end
def foreign_key_present? def foreign_key_present?
owner[reflection.foreign_key] owner._read_attribute(reflection.foreign_key)
end end
# NOTE - for now, we're only supporting inverse setting from belongs_to back onto # NOTE - for now, we're only supporting inverse setting from belongs_to back onto
@ -99,12 +99,13 @@ def target_id
if options[:primary_key] if options[:primary_key]
owner.send(reflection.name).try(:id) owner.send(reflection.name).try(:id)
else else
owner[reflection.foreign_key] owner._read_attribute(reflection.foreign_key)
end end
end end
def stale_state def stale_state
owner[reflection.foreign_key] && owner[reflection.foreign_key].to_s result = owner._read_attribute(reflection.foreign_key)
result && result.to_s
end end
end end
end end