Created
July 28, 2015 23:29
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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