module Draper class Base require 'active_support/core_ext/class/attribute' class_attribute :denied, :allowed, :model_class attr_accessor :context, :model DEFAULT_DENIED = Object.new.methods << :method_missing FORCED_PROXY = [:to_param] self.denied = DEFAULT_DENIED def initialize(input, context = nil) input.inspect self.class.model_class = input.class if model_class.nil? @model = input self.context = context build_methods end def self.find(input) self.new(model_class.find(input)) end def self.decorates(input) self.model_class = input.to_s.camelize.constantize model_class.send :include, Draper::ModelSupport end def self.denies(*input_denied) raise ArgumentError, "Specify at least one method (as a symbol) to exclude when using denies" if input_denied.empty? raise ArgumentError, "Use either 'allows' or 'denies', but not both." if self.allowed? self.denied += input_denied end def self.allows(*input_allows) raise ArgumentError, "Specify at least one method (as a symbol) to allow when using allows" if input_allows.empty? raise ArgumentError, "Use either 'allows' or 'denies', but not both." unless (self.denied == DEFAULT_DENIED) self.allowed = input_allows end def self.decorate(input, context = nil) input.respond_to?(:each) ? input.map{|i| new(i, context)} : new(input, context) end def helpers @helpers ||= ApplicationController::all_helpers end alias :h :helpers def self.lazy_helpers self.send(:include, Draper::LazyHelpers) end def self.model_name ActiveModel::Name.new(model_class) end def to_model @model end private def select_methods specified = self.allowed || (model.public_methods.map{|s| s.to_sym} - denied.map{|s| s.to_sym}) (specified - self.public_methods.map{|s| s.to_sym}) + FORCED_PROXY end def build_methods select_methods.each do |method| (class << self; self; end).class_eval do define_method method do |*args, &block| model.send method, *args, &block end end end end end end