Kamil Lelonek
Kamil Lelonek

Reputation: 14744

autoloading in production

I have all my controllers declared as a

class Api::V1::SomeController < Api::V1::ApiController; (...); end

where

class Api::V1::ApiController < ApplicationController; end

All my controllers are placed in /app/controllers/api/v1/*_controller.rb, ApplicationController is under app/controllers/application_controller.rb.

On development everything works fine, but I have problem with requiring and loading controllers wrapped in api versioning namespace in production.

In production environment (locally or heroku) I got: LoadError (Unable to autoload constant Api::V1::SomeController, expected /app/app/controllers/api/v1/some_controller.rb to define it):

What is the correct way to configure app/config/environments/production.rb and require versioning api on production environment.

Upvotes: 0

Views: 509

Answers (1)

pdobb
pdobb

Reputation: 18037

I'm pretty sure you'll get around this issue by taking a modular approach to defining all of your namespaced classes. For example:

module Api
  module V1
    class SomeController < ApiController
      # ...
    end
  end
end

And:

module Api
  module V1
    class ApiController < ::ApplicationController
      # ...
    end
  end
end

Using this pattern disambiguates the namespaces for autoloading in Rails. Autoloading is a fairly complex mechanism... (And does seem to behave differently between development and production!) If you'd like to learn more of the inner workings this article is well worth the read.

UPDATE

The :: in ::ApplicationController means "with no namespace" or the "default namespace". That part is probably not needed in this case since you probably only have one ApplicationController constant defined.

The difference this approach creates is that it ensures that Rails will not "skip over" your constant definition, so to speak. The article I linked above explains it by example.

Upvotes: 2

Related Questions