Created
December 14, 2008 08:07
-
-
Save boof/35652 to your computer and use it in GitHub Desktop.
Polymorphisms for polymorphic resource controllers
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
class Polymorphism | |
attr_reader :base, :ctrl, :path | |
@@polymorph = '' | |
@@polymorphs = '' | |
cattr_reader :polymorph, :polymorphs | |
def self.set_polymorph(polymorph) | |
@@polymorph = "#{ polymorph }" | |
@@polymorphs = "#{ polymorph }".pluralize | |
end | |
@@namespace = '' | |
cattr_reader :namespace | |
def self.set_namespace(namespace) | |
@@namespace = namespace | |
end | |
def self.inherited(base) | |
if @@polymorph.blank? | |
basename = base.name.demodulize | |
# strip "Polymorphism" | |
basename = basename[0..-13] if basename[-12, 12] == 'Polymorphism' | |
base.set_polymorph basename.underscore | |
end | |
end | |
def initialize(ctrl) | |
@ctrl = ctrl | |
@key = ctrl.params.keys.find { |key| key =~ /(.+)_id$/ } | |
@base = $~[1] | |
@path = Path.new self | |
end | |
def proxy_target_id | |
@ctrl.params[:id].to_i | |
end | |
def proxy_target_class | |
@proxy_target_class ||= polymorph.classify.constantize | |
end | |
def proxy_owner_id | |
@ctrl.params[@key].to_i | |
end | |
def proxy_owner_class | |
@proxy_owner_class ||= base.classify.constantize | |
end | |
def association_reflection | |
@association_reflection ||= | |
proxy_owner_class.reflect_on_association(polymorph.to_sym) || | |
proxy_owner_class.reflect_on_association(polymorphs.to_sym) | |
end | |
def singular? | |
association_reflection.macro == :has_one | |
end | |
def plural?() | |
association_reflection.macro == :has_many | |
end | |
def proxy_owner | |
proxy_owner_class.find proxy_owner_id | |
end | |
def proxy | |
proxy_owner.send association_reflection.name | |
end | |
def proxy_target | |
proxy_target_class.find proxy_target_id | |
end | |
def proxy_collection | |
proxy_target_class.find :all, :conditions => { | |
"#{ association_reflection.as }_type" => proxy_owner_class.base_class.name, | |
"#{ association_reflection.as }_id" => proxy_owner_id | |
} | |
end | |
class Path | |
def initialize(polymorphism) | |
@polymorphism = polymorphism | |
end | |
def index | |
generate nil, polymorphs | |
rescue | |
generate nil, polymorph | |
end | |
def show(proxy_target = @polymorphism.proxy_target) | |
generate nil, proxy_target | |
end | |
def new | |
generate :new, proxy_target_class.new | |
end | |
def edit(proxy_target = @polymorphism.proxy_target) | |
generate :edit, proxy_target | |
end | |
def collection(action, *args) | |
prefix = '' | |
prefix << "#{ action }_" if action | |
prefix << "#{ namespace }_" if namespace | |
ctrl.send :"#{ prefix }#{ base }_#{ polymorphs }_path", | |
proxy_owner, *args | |
end | |
def generate(action = nil, *args) | |
action &&= "#{ action }_" | |
ctrl.send :"#{ action }polymorphic_path", | |
[namespace, proxy_owner, *args].compact | |
end | |
protected | |
def base | |
@polymorphism.base | |
end | |
def polymorph | |
@polymorphism.polymorph | |
end | |
def polymorphs | |
@polymorphism.polymorphs | |
end | |
def namespace | |
@polymorphism.namespace | |
end | |
def ctrl | |
@polymorphism.ctrl | |
end | |
def proxy_owner | |
@polymorphism.proxy_owner | |
end | |
def proxy_target_class | |
@polymorphism.proxy_target_class | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment