Skip to content

Instantly share code, notes, and snippets.

@stanio
Created June 29, 2015 14:38
Show Gist options
  • Save stanio/5d25bd528e6d6644132d to your computer and use it in GitHub Desktop.
Save stanio/5d25bd528e6d6644132d to your computer and use it in GitHub Desktop.
ActiveRecord Reference Proxy (lazy-load)
require 'active_record'
module ActiveRecord
#
# @see http://stackoverflow.com/questions/28434966/lazy-load-activerecord-proxy-instance Lazy-load ActiveRecord proxy instance
#
class Reference < ActiveSupport::ProxyObject
def initialize(record_class, primary_key)
raise ArgumentError, "Illegal record type: #{record_class.class}" unless record_class.is_a? Class
raise ArgumentError, "Not an ActiveRecord type: #{record_class}" unless record_class < ActiveRecord::Base
raise ArgumentError, "No primary key given" unless primary_key.present?
@type = record_class
@id = primary_key
end
def __record__
unless defined? @record
@record = @type.find(@id)
end
@record
end
private :__record__
def method_missing(name, *a, &b)
if defined? @record
@record.public_send(name, *a, &b)
elsif name == :class
@type
elsif name.to_s == @type.primary_key
@id
else
__record__.public_send(name, *a, &b)
end
end
def respond_to_missing?(name, *a, &b)
name == :class || name.to_s == @type.primary_key || __record__.respond_to?(name, *a, &b)
end
end
#
# class User < ActiveRecord::Base; end
#
# user = User.find(user_id)
# user = User.reference(user_id)
#
class Base
def self.reference(primary_key)
Reference.new(self.class, primary_key)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment