From 6c78b6cca629c9b7d2663a6712150e582fd6af3e Mon Sep 17 00:00:00 2001 From: Jeff Casimir Date: Wed, 13 Jul 2011 01:00:10 -0400 Subject: [PATCH] Sleepy cowboy coding on the train --- lib/draper.rb | 7 ++- lib/draper/all_helpers.rb | 43 +++++++++++++++++++ lib/draper/base.rb | 13 +++--- lib/draper/lazy_helpers.rb | 11 +++++ lib/draper/system.rb | 7 +++ .../draper/model/templates/model.rb | 23 +++++----- 6 files changed, 85 insertions(+), 19 deletions(-) create mode 100644 lib/draper/all_helpers.rb create mode 100644 lib/draper/lazy_helpers.rb create mode 100644 lib/draper/system.rb diff --git a/lib/draper.rb b/lib/draper.rb index f78bc08..2f9b9a6 100644 --- a/lib/draper.rb +++ b/lib/draper.rb @@ -1,2 +1,7 @@ require "draper/version" -require 'draper/base' \ No newline at end of file +require 'draper/system' +require 'draper/all_helpers' +require 'draper/base' +require 'draper/lazy_helpers' + +Draper::System.setup \ No newline at end of file diff --git a/lib/draper/all_helpers.rb b/lib/draper/all_helpers.rb new file mode 100644 index 0000000..4222ac5 --- /dev/null +++ b/lib/draper/all_helpers.rb @@ -0,0 +1,43 @@ +module Draper + module AllHelpers + # Provide access to helper methods from outside controllers and views, + # such as in Presenter objects. Rails provides ActionController::Base.helpers, + # but this does not include any of our application helpers. + def all_helpers + @all_helpers_proxy ||= begin + # Start with just the rails helpers. This is the same method used + # by ActionController::Base.helpers + # proxy = ActionView::Base.new.extend(_helpers) + proxy = ActionController::Base.helpers + + # url_for depends on _routes method being defined + proxy.instance_eval do + def _routes + Rails.application.routes + end + end + + # Import all named path methods + proxy.extend(Rails.application.routes.named_routes.module) + + # Load all our application helpers to extend + modules_for_helpers([:all]).each do |mod| + proxy.extend(mod) + end + + proxy.instance_eval do + # A hack since this proxy doesn't pick up default_url_options from anywhere + def url_for(*args) + if args.last.is_a?(Hash) && !args.last[:only_path] + args = args.dup + args << args.pop.merge(host: ActionMailer::Base.default_url_options[:host]) + end + super(*args) + end + end + + proxy + end + end + end +end \ No newline at end of file diff --git a/lib/draper/base.rb b/lib/draper/base.rb index 6b19c05..9f28d01 100644 --- a/lib/draper/base.rb +++ b/lib/draper/base.rb @@ -1,14 +1,10 @@ module Draper - class Base - include ActionView::Helpers::TagHelper - include ActionView::Helpers::UrlHelper - include ActionView::Helpers::TextHelper - + class Base require 'active_support/core_ext/class/attribute' class_attribute :denied, :allowed, :source_class attr_accessor :source - DEFAULT_DENIED = Object.new.methods << :method_missing + DEFAULT_DENIED = Object.new.methods self.denied = DEFAULT_DENIED def initialize(subject) @@ -35,13 +31,14 @@ module Draper end def helpers - ActionController::Base.helpers + @helpers ||= ApplicationController::all_helpers end + alias :h :helpers def self.model_name ActiveModel::Name.new(source_class) end - + private def select_methods self.allowed || (source.public_methods - denied) diff --git a/lib/draper/lazy_helpers.rb b/lib/draper/lazy_helpers.rb new file mode 100644 index 0000000..277efc0 --- /dev/null +++ b/lib/draper/lazy_helpers.rb @@ -0,0 +1,11 @@ +module Draper + module LazyHelpers + def method_missing(method_name, *args, &block) + begin + helpers.send method_name, *args, &block + rescue NoMethodError + super + end + end + end +end \ No newline at end of file diff --git a/lib/draper/system.rb b/lib/draper/system.rb new file mode 100644 index 0000000..bc7bd40 --- /dev/null +++ b/lib/draper/system.rb @@ -0,0 +1,7 @@ +module Draper + class System + def self.setup + ActionController::Base.send(:extend, Draper::AllHelpers) + end + end +end \ No newline at end of file diff --git a/lib/generators/draper/model/templates/model.rb b/lib/generators/draper/model/templates/model.rb index 5e71d5e..c32a65e 100644 --- a/lib/generators/draper/model/templates/model.rb +++ b/lib/generators/draper/model/templates/model.rb @@ -1,24 +1,27 @@ class <%= singular_name.camelize %>Decorator < Draper::Base - # Rails Helpers - # Rails helpers like content_tag, link_to, and pluralize are already - # available to you. If you need access to other helpers, include them - # like this: - # include ActionView::Helpers::TextHelper - # Or pull in the whole kitchen sink: - # include ActionView::Helpers + # Helpers from Rails an Your Application + # You can access any helper via a proxy to ApplicationController + # + # Normal Usage: helpers.number_to_currency(2) + # Abbreviated : h.number_to_currency(2) + # + # You can optionally enable "lazy helpers" by including this module: + # include Draper::LazyHelpers + # Then use the helpers with no prefix: + # number_to_currency(2) # Wrapper Methods # Control access to the wrapped subject's methods using one of the following: # - # To allow _only_ the listed methods: + # To allow only the listed methods (whitelist): # allows :method1, :method2 # - # To allow everything _except_ the listed methods: + # To allow everything except the listed methods (blacklist): # denies :method1, :method2 # Presentation Methods - # Define presentation-related instance methods. Ex: + # Define your own instance methods. Ex: # def formatted_created_at # content_tag :span, created_at.strftime("%A") # end