Skip to content

Instantly share code, notes, and snippets.

@roniegh
Created July 28, 2015 23:29
Show Gist options
  • Save roniegh/5e6b4564989f9bf7ee4e to your computer and use it in GitHub Desktop.
Save roniegh/5e6b4564989f9bf7ee4e to your computer and use it in GitHub Desktop.
Rails ActiveRecord 2.3.15 hash that supports procs as values (can be used with ActiveRecord default_scope)
module Proxies
# ProxyHash can be used when there is a need to have procs inside hashes, as it executes all procs before returning the hash
# ==== Example
# Proxies::ProxyHash.new(:company_id => lambda{logged_user.try(:company_id)})
class ProxyHash < ::Hash
instance_methods.each{|m| undef_method m unless m =~ /(^__|^nil\?$|^method_missing$|^object_id$|proxy_|^respond_to\?$|^send$)/}
def [](_key)
call_hash_procs(@target, @original_hash)
ProxyHash.new(@original_hash[_key])
end
# Returns the \target of the proxy, same as +target+.
def proxy_target
@target
end
# Does the proxy or its \target respond to +symbol+?
def respond_to?(*args)
super(*args) || @target.respond_to?(*args)
end
# Returns the target of this proxy, same as +proxy_target+.
def target
@target
end
# Sets the target of this proxy to <tt>\target</tt>.
def target=(target)
@target = target
end
def send(method, *args)
if respond_to?(method)
super
else
@target.send(method, *args)
end
end
def initialize(*_find_args)
@original_hash = _find_args.extract_options!
@target = @original_hash.deep_dup
end
private
# Forwards any missing method call to the \target.
def method_missing(method, *args, &block)
if @target.respond_to?(method)
call_hash_procs(@target, @original_hash)
@target.send(method, *args, &block)
else
super
end
end
def call_hash_procs(_hash, _original_hash)
_hash.each do |_key, _value|
if _value.is_a?(Hash)
call_hash_procs(_value, _original_hash[_key]) if _original_hash.has_key?(_key)
else
_hash[_key] = _original_hash[_key].call if _original_hash[_key].is_a?(Proc)
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment