ruby-on-railsrubyspreespree-auth-devise

How can I extend my controller from installed Spree gem's controller?


I have spree gem installed successfully. I don't need spree_frontend. Here is the Gemfile

gem 'spree_core', '4.2.0.rc2'
gem 'spree_backend', '4.2.0.rc2'
gem 'spree_sample', '4.2.0.rc2'
gem 'spree_cmd', '4.2.0.rc2'
gem 'spree_auth_devise', '~> 4.2'

So I want to extend my ApplicationController from Spree's BaseController. Here is the code:

class ApplicationController < Spree::BaseController
  include Spree::Core::ControllerHelpers::Order
end

But I get following errors:

uninitialized constant Spree::BaseController (NameError)

How can I extend my controller from installed Spree gem's controller?


Solution

  • The problem you're running into is that Spree::BaseController already inherits from ApplicationController; see https://github.com/spree/spree/blob/master/core/app/controllers/spree/base_controller.rb. This is to allow your ApplicationController to define things like current_user and similar basic functions before Spree sees it.

    Declaring them the other way around as well creates a circular dependency, and the class loading fails as a result. Without changing Spree itself, the only fix is to do something else.

    Instead, to have your controllers use Spree::BaseController as a superclass, first define ApplicationController in the more usual fashion e.g.:

    # app/controllers/application_controller.rb
    class ApplicationController < ActionController::Base
      # ...
    end
    

    then invent a new abstract controller, for your own use, that inherits from Spree, e.g. let's name it StoreBaseController:

    # app/controllers/store_base_controller.rb
    class StoreBaseController < Spree::BaseController
      include Spree::Core::ControllerHelpers::Order
      # ...
    end
    

    This StoreBaseController can now be used in place of ApplicationController when defining more specific controllers. It works because it doesn't create a loop in the inheritance tree, which now looks like this:

    Controller Hierarchy

    Note: if you're also using the rails generator command to produce controllers or scaffolds from templates, be aware that the generator has ApplicationController hard-coded in the templates, so you'll need to amend them once created.