diff options
author | Jon Leighton <j@jonathanleighton.com> | 2010-12-22 20:57:41 +0000 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2010-12-23 15:19:18 -0800 |
commit | 2d9626fc74c2d57f90c856c37e5967bbe6651bd8 (patch) | |
tree | 067d9d8015680e1df6308aeff4fe9bf3e8fb33e0 /activerecord/lib/active_record/associations | |
parent | 3f17ed407c5d61bc01fd59776205486c2350f36e (diff) | |
download | rails-2d9626fc74c2d57f90c856c37e5967bbe6651bd8.tar.gz rails-2d9626fc74c2d57f90c856c37e5967bbe6651bd8.tar.bz2 rails-2d9626fc74c2d57f90c856c37e5967bbe6651bd8.zip |
Improved strategy for updating a belongs_to association when the foreign key changes. Rather than resetting each affected association when the foreign key changes, we should lazily check for 'staleness' (where fk does not match target id) when the association is accessed.
Diffstat (limited to 'activerecord/lib/active_record/associations')
3 files changed, 27 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb index 252ff7e7ea..f4eceeed8c 100644 --- a/activerecord/lib/active_record/associations/association_proxy.rb +++ b/activerecord/lib/active_record/associations/association_proxy.rb @@ -130,6 +130,16 @@ module ActiveRecord @loaded = true end + # The target is stale if the target no longer points to the record(s) that the + # relevant foreign_key(s) refers to. If stale, the association accessor method + # on the owner will reload the target. It's up to subclasses to implement this + # method if relevant. + # + # Note that if the target has not been loaded, it is not considered stale. + def stale_target? + false + end + # Returns the target of this proxy, same as +proxy_target+. def target @target diff --git a/activerecord/lib/active_record/associations/belongs_to_association.rb b/activerecord/lib/active_record/associations/belongs_to_association.rb index b438620c8f..c9abfe36e8 100644 --- a/activerecord/lib/active_record/associations/belongs_to_association.rb +++ b/activerecord/lib/active_record/associations/belongs_to_association.rb @@ -42,6 +42,14 @@ module ActiveRecord @updated end + def stale_target? + if @target && @target.persisted? + @target.send(@reflection.association_primary_key).to_i != @owner.send(@reflection.primary_key_name).to_i + else + false + end + end + private def find_target find_method = if @reflection.options[:primary_key] diff --git a/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb b/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb index a0df860623..844ae94c3d 100644 --- a/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb +++ b/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb @@ -23,6 +23,15 @@ module ActiveRecord @updated end + def stale_target? + if @target && @target.persisted? + @target.send(@reflection.association_primary_key).to_i != @owner.send(@reflection.primary_key_name).to_i || + @target.class.base_class.name.to_s != @owner.send(@reflection.options[:foreign_type]).to_s + else + false + end + end + private # NOTE - for now, we're only supporting inverse setting from belongs_to back onto |