diff --git a/README.md b/README.md index a98c325..2b1068c 100644 --- a/README.md +++ b/README.md @@ -368,6 +368,18 @@ you'll have access to an ArticleDecorator object instead. In your controller you can continue to use the `@article` instance variable to manipulate the model - for example, `@article.comments.build` to add a new blank comment for a form. +## Configuration +Draper works out the box well, but also provides a hook for you to configure its +default functionality. For example, Draper assumes you have a base `ApplicationController`. +If your base controller is named something different (e.g. `BaseController`), +you can tell Draper to use it by adding the following to an initializer: + +```ruby +Draper.configure do |config| + config.default_controller = BaseController +end +``` + ## Testing Draper supports RSpec, MiniTest::Rails, and Test::Unit, and will add the diff --git a/lib/draper.rb b/lib/draper.rb index 5473bbb..1c331e0 100644 --- a/lib/draper.rb +++ b/lib/draper.rb @@ -9,6 +9,7 @@ require 'active_support/core_ext/hash/reverse_merge' require 'active_support/core_ext/name_error' require 'draper/version' +require 'draper/configuration' require 'draper/view_helpers' require 'draper/delegation' require 'draper/automatic_delegation' @@ -27,6 +28,8 @@ require 'draper/decorates_assigned' require 'draper/railtie' if defined?(Rails) module Draper + extend Draper::Configuration + def self.setup_action_controller(base) base.class_eval do include Draper::ViewContext diff --git a/lib/draper/configuration.rb b/lib/draper/configuration.rb new file mode 100644 index 0000000..1e21087 --- /dev/null +++ b/lib/draper/configuration.rb @@ -0,0 +1,15 @@ +module Draper + module Configuration + def configure + yield self + end + + def default_controller + @@default_controller ||= ApplicationController + end + + def default_controller=(controller) + @@default_controller = controller + end + end +end diff --git a/lib/draper/railtie.rb b/lib/draper/railtie.rb index 12e19fb..556c15a 100644 --- a/lib/draper/railtie.rb +++ b/lib/draper/railtie.rb @@ -3,8 +3,6 @@ require 'rails/railtie' module ActiveModel class Railtie < Rails::Railtie generators do |app| - app ||= Rails.application # Rails 3.0.x does not yield `app` - Rails::Generators.configure! app.config.generators require_relative '../generators/controller_override' end @@ -13,7 +11,6 @@ end module Draper class Railtie < Rails::Railtie - config.after_initialize do |app| app.config.paths.add 'app/decorators', eager_load: true @@ -23,19 +20,19 @@ module Draper end end - initializer "draper.setup_action_controller" do |app| + initializer 'draper.setup_action_controller' do ActiveSupport.on_load :action_controller do Draper.setup_action_controller self end end - initializer "draper.setup_action_mailer" do |app| + initializer 'draper.setup_action_mailer' do ActiveSupport.on_load :action_mailer do Draper.setup_action_mailer self end end - initializer "draper.setup_orm" do |app| + initializer 'draper.setup_orm' do [:active_record, :mongoid].each do |orm| ActiveSupport.on_load orm do Draper.setup_orm self @@ -43,26 +40,22 @@ module Draper end end - initializer "draper.minitest-rails_integration" do |app| + initializer 'draper.minitest-rails_integration' do ActiveSupport.on_load :minitest do - require "draper/test/minitest_integration" + require 'draper/test/minitest_integration' end end - console do + def initialize_view_context require 'action_controller/test_case' - ApplicationController.new.view_context + Draper.default_controller.new.view_context Draper::ViewContext.build end - runner do - require 'action_controller/test_case' - ApplicationController.new.view_context - Draper::ViewContext.build - end + console { initialize_view_context } - rake_tasks do - Dir[File.join(File.dirname(__FILE__),'tasks/*.rake')].each { |f| load f } - end + runner { initialize_view_context } + + rake_tasks { Dir[File.join(File.dirname(__FILE__), 'tasks/*.rake')].each { |f| load f } } end end diff --git a/lib/draper/view_context/build_strategy.rb b/lib/draper/view_context/build_strategy.rb index 94fef2b..3620e75 100644 --- a/lib/draper/view_context/build_strategy.rb +++ b/lib/draper/view_context/build_strategy.rb @@ -37,7 +37,8 @@ module Draper attr_reader :block def controller - (Draper::ViewContext.controller || ApplicationController.new).tap do |controller| + Draper::ViewContext.controller ||= Draper.default_controller.new + Draper::ViewContext.controller.tap do |controller| controller.request ||= new_test_request controller if defined?(ActionController::TestRequest) end end diff --git a/spec/draper/configuration_spec.rb b/spec/draper/configuration_spec.rb new file mode 100644 index 0000000..23d7d91 --- /dev/null +++ b/spec/draper/configuration_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +module Draper + RSpec.describe Configuration do + it 'yields Draper on configure' do + Draper.configure { |config| expect(config).to be Draper } + end + + it 'defaults default_controller to ApplicationController' do + expect(Draper.default_controller).to be ApplicationController + end + + it 'allows customizing default_controller through configure' do + default = Draper.default_controller + + Draper.configure do |config| + config.default_controller = CustomController + end + + expect(Draper.default_controller).to be CustomController + + Draper.default_controller = default + end + end +end diff --git a/spec/draper/view_context/build_strategy_spec.rb b/spec/draper/view_context/build_strategy_spec.rb index f6a3e36..58bdf7a 100644 --- a/spec/draper/view_context/build_strategy_spec.rb +++ b/spec/draper/view_context/build_strategy_spec.rb @@ -23,11 +23,10 @@ module Draper context "when a current controller is not set" do it "uses ApplicationController" do - view_context = fake_view_context - stub_const "ApplicationController", double(new: fake_controller(view_context)) - strategy = ViewContext::BuildStrategy::Full.new - - expect(strategy.call).to be view_context + expect(Draper::ViewContext.controller).to be_nil + view_context = ViewContext::BuildStrategy::Full.new.call + expect(view_context.controller).to eq Draper::ViewContext.controller + expect(view_context.controller).to be_an ApplicationController end end diff --git a/spec/dummy/app/controllers/application_controller.rb b/spec/dummy/app/controllers/application_controller.rb deleted file mode 100644 index bbe1d38..0000000 --- a/spec/dummy/app/controllers/application_controller.rb +++ /dev/null @@ -1,4 +0,0 @@ -class ApplicationController < ActionController::Base - include LocalizedUrls - protect_from_forgery -end diff --git a/spec/dummy/app/controllers/base_controller.rb b/spec/dummy/app/controllers/base_controller.rb new file mode 100644 index 0000000..d9e9218 --- /dev/null +++ b/spec/dummy/app/controllers/base_controller.rb @@ -0,0 +1,4 @@ +class BaseController < ActionController::Base + include LocalizedUrls + protect_from_forgery +end diff --git a/spec/dummy/app/controllers/posts_controller.rb b/spec/dummy/app/controllers/posts_controller.rb index 1993005..d5de64b 100644 --- a/spec/dummy/app/controllers/posts_controller.rb +++ b/spec/dummy/app/controllers/posts_controller.rb @@ -1,4 +1,4 @@ -class PostsController < ApplicationController +class PostsController < BaseController decorates_assigned :post def show diff --git a/spec/dummy/config/initializers/draper.rb b/spec/dummy/config/initializers/draper.rb new file mode 100644 index 0000000..414d9d6 --- /dev/null +++ b/spec/dummy/config/initializers/draper.rb @@ -0,0 +1,3 @@ +Draper.configure do |config| + config.default_controller = BaseController +end diff --git a/spec/dummy/spec/decorators/post_decorator_spec.rb b/spec/dummy/spec/decorators/post_decorator_spec.rb index 57830ad..e1655b9 100644 --- a/spec/dummy/spec/decorators/post_decorator_spec.rb +++ b/spec/dummy/spec/decorators/post_decorator_spec.rb @@ -58,7 +58,7 @@ describe PostDecorator do expect(xml).to have_css "post > updated-at", text: "overridden" end - it "uses a test view context from ApplicationController" do - expect(Draper::ViewContext.current.controller).to be_an ApplicationController + it "uses a test view context from BaseController" do + expect(Draper::ViewContext.current.controller).to be_an BaseController end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 57aa9cf..63aba93 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -30,6 +30,9 @@ module Namespaced class OtherDecorator < Draper::Decorator; end end +ApplicationController = Class.new(ActionController::Base) +CustomController = Class.new(ActionController::Base) + # After each example, revert changes made to the class def protect_class(klass) before { stub_const klass.name, Class.new(klass) }