Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for custom default controller configuration #788

Merged
merged 7 commits into from
Mar 31, 2017
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions lib/draper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
require 'active_support/core_ext/name_error'

require 'draper/version'
require 'draper/configuration'
require 'draper/view_helpers'
require 'draper/delegation'
require 'draper/automatic_delegation'
Expand All @@ -27,6 +28,8 @@
require 'draper/railtie' if defined?(Rails)

module Draper
extend Draper::Configuration

def self.setup_action_controller(base)
base.class_eval do
include Draper::ViewContext
Expand Down
15 changes: 15 additions & 0 deletions lib/draper/configuration.rb
Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions lib/draper/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ class Railtie < Rails::Railtie

console do
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.default_controller.new.view_context
Draper::ViewContext.build
end

Expand Down
2 changes: 1 addition & 1 deletion lib/draper/view_context/build_strategy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def call
attr_reader :block

def controller
(Draper::ViewContext.controller || ApplicationController.new).tap do |controller|
(Draper::ViewContext.controller || Draper.default_controller.new).tap do |controller|
controller.request ||= new_test_request controller if defined?(ActionController::TestRequest)
end
end
Expand Down
27 changes: 27 additions & 0 deletions spec/draper/configuration_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
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
skip
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests all pass every time when I run just this file. However, these last two tests cause the entire suite to fail with an error about leaking a double. Due to it being a state leaking issue, it's not a consistent test that fails. The two different errors that keep seeing are:
image

and

image

I'm not sure how to go about fixing those as I'm not super familiar with the test setup on this project. I will continue to look into it, but could use some advice if someone has some.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was able to fix this issue. The problem was that one of the tests in the build_strategy_spec.rb was stubbing a constant that was overriding the new class definition in the spec_helper.rb. The specific test that was stubbing was able to be re-written without mocks now that the ApplicationController class is defined. I believe the way I re-wrote the test still tests for the same functionality. Somebody correct me if that's not the case. The commit is here:
a886d28

expect(Draper.default_controller).to be ApplicationController
end

it 'allows customizing default_controller through configure' do
skip
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
3 changes: 3 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ class ProductDecorator < Draper::Decorator; end
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) }
Expand Down