From 0b03d9c21ed3dd384e3e48adeae6463ee4d12aa4 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 16 Jul 2012 12:43:29 -0400 Subject: [PATCH] Monkeypatch ActionController::Base. We need to be able to let draper get a copy of the view_context no matter what happens. AC::Base doesn't really let us do that. So we have to monkeypatch. This was originally suggested in https://github.com/jcasimir/draper/issues/124#issuecomment-6954291 by @rf-. It appears to be the cleanest way to take care of this problem, and shouldn't affect any other things, since we keep the exact same semantics of view_context. Theoretically: Fixes #124 Fixes #109 --- lib/draper.rb | 1 + lib/draper/action_controller/base.rb | 9 +++++++++ lib/draper/system.rb | 1 - lib/draper/test/view_context.rb | 2 +- lib/draper/view_context.rb | 10 ---------- spec/draper/base_spec.rb | 2 +- spec/draper/view_context_spec.rb | 13 ------------- spec/spec_helper.rb | 10 +++++++++- spec/support/samples/application_controller.rb | 17 ++++++++--------- 9 files changed, 29 insertions(+), 36 deletions(-) create mode 100644 lib/draper/action_controller/base.rb diff --git a/lib/draper.rb b/lib/draper.rb index f4fa08e..aef6808 100644 --- a/lib/draper.rb +++ b/lib/draper.rb @@ -10,6 +10,7 @@ require 'draper/helper_support' require 'draper/view_context' require 'draper/decorated_enumerable_proxy' require 'draper/railtie' if defined?(Rails) +require 'draper/action_controller/base' # Test Support require 'draper/test/rspec_integration' if defined?(RSpec) and RSpec.respond_to?(:configure) diff --git a/lib/draper/action_controller/base.rb b/lib/draper/action_controller/base.rb new file mode 100644 index 0000000..898065f --- /dev/null +++ b/lib/draper/action_controller/base.rb @@ -0,0 +1,9 @@ +module DraperViewContext + def view_context + super.tap do |context| + Draper::ViewContext.current = context + end + end +end + +ApplicationController.send(:include, DraperViewContext) diff --git a/lib/draper/system.rb b/lib/draper/system.rb index 2c66c27..aff8d8b 100644 --- a/lib/draper/system.rb +++ b/lib/draper/system.rb @@ -2,7 +2,6 @@ module Draper class System def self.setup(component) component.class_eval do - include Draper::ViewContextFilter extend Draper::HelperSupport unless defined?(::ActionMailer) && self.is_a?(::ActionMailer::Base) end end diff --git a/lib/draper/test/view_context.rb b/lib/draper/test/view_context.rb index 3e22c66..422e7c7 100644 --- a/lib/draper/test/view_context.rb +++ b/lib/draper/test/view_context.rb @@ -2,7 +2,7 @@ module Draper module ViewContext def self.infect!(context) context.instance_eval do - ApplicationController.new.set_current_view_context + ApplicationController.new.view_context Draper::ViewContext.current.controller.request ||= ActionController::TestRequest.new Draper::ViewContext.current.request ||= Draper::ViewContext.current.controller.request Draper::ViewContext.current.params ||= {} diff --git a/lib/draper/view_context.rb b/lib/draper/view_context.rb index 8a0bb13..b593dbf 100644 --- a/lib/draper/view_context.rb +++ b/lib/draper/view_context.rb @@ -8,14 +8,4 @@ module Draper Thread.current[:current_view_context] = input end end - - module ViewContextFilter - def set_current_view_context - Draper::ViewContext.current = self.view_context - end - - def self.included(source) - source.send(:before_filter, :set_current_view_context) if source.respond_to?(:before_filter) - end - end end diff --git a/spec/draper/base_spec.rb b/spec/draper/base_spec.rb index 1c810d6..736c2c6 100755 --- a/spec/draper/base_spec.rb +++ b/spec/draper/base_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe Draper::Base do - before(:each){ ApplicationController.new.set_current_view_context } + before(:each){ ApplicationController.new.view_context } subject{ Decorator.new(source) } let(:source){ Product.new } let(:non_active_model_source){ NonActiveModelProduct.new } diff --git a/spec/draper/view_context_spec.rb b/spec/draper/view_context_spec.rb index 4025942..9c9c054 100644 --- a/spec/draper/view_context_spec.rb +++ b/spec/draper/view_context_spec.rb @@ -5,19 +5,6 @@ describe Draper::ViewContext do let(:app_controller) { ApplicationController } let(:app_controller_instance) { app_controller.new } - it "implements #set_current_view_context" do - app_controller_instance.should respond_to(:set_current_view_context) - end - - it "calls #before_filter with #set_current_view_context" do - app_controller.before_filters.should include(:set_current_view_context) - end - - it "raises an exception if the view_context is fetched without being set" do - Draper::ViewContext.current = nil - expect {app_controller.current_view_context}.should raise_exception(Exception) - end - it "provides a method to create a view context while testing" do Draper::ViewContext.should respond_to(:infect!) end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 71e67d5..fc3831f 100755 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -2,11 +2,13 @@ require 'bundler/setup' require 'ammeter/init' require 'rails' +require 'action_view' +require './spec/support/samples/application_controller' + Bundler.require require './spec/support/samples/active_model' require './spec/support/samples/active_record' -require './spec/support/samples/application_controller' require './spec/support/samples/application_helper' require './spec/support/samples/decorator' require './spec/support/samples/decorator_with_allows' @@ -24,3 +26,9 @@ require './spec/support/samples/some_thing' require './spec/support/samples/some_thing_decorator' require './spec/support/samples/widget' require './spec/support/samples/widget_decorator' + +module ActionController + class Base + Draper::System.setup(self) + end +end diff --git a/spec/support/samples/application_controller.rb b/spec/support/samples/application_controller.rb index e056e74..0f4ca7a 100644 --- a/spec/support/samples/application_controller.rb +++ b/spec/support/samples/application_controller.rb @@ -10,7 +10,14 @@ module ActionController @@before_filters << name end - Draper::System.setup(self) + def view_context +# puts "zomg view context" + @view_context ||= ApplicationController + end + + def view_context=(input) + @view_context = input + end end end @@ -20,14 +27,6 @@ class ApplicationController < ActionController::Base extend ActionView::Helpers::UrlHelper extend ApplicationHelper - def view_context - @view_context ||= ApplicationController - end - - def view_context=(input) - @view_context = input - end - def self.hello "Hello!" end