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
def different_target?(record)
record.id != owner[reflection.foreign_key]
record.id != owner._read_attribute(reflection.foreign_key)
end
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
def remove_keys
@ -85,7 +85,7 @@ def remove_keys
end
def foreign_key_present?
owner[reflection.foreign_key]
owner._read_attribute(reflection.foreign_key)
end
# 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]
owner.send(reflection.name).try(:id)
else
owner[reflection.foreign_key]
owner._read_attribute(reflection.foreign_key)
end
end
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