Sig
Sig

Reputation: 5986

How can I tell Rails to autoload namespaced models from a top-level directory?

How can I tell Rails (5 beta3) to look for namespaced models in app/models instead of in app/models/namespace?

I have

module MyApp
  class User < ApplicationRecord
    ...
  end
end

and if I put it in app/models/myapp Rails finds it. However, since all my models will be within the MyApp module I'd rather keep them in app/models.

Thanks

Upvotes: 2

Views: 787

Answers (1)

Dave Schweisguth
Dave Schweisguth

Reputation: 37657

No, you can't tell Rails to look for a qualified constant (like MyApp::User) at the top level of a directory in the autoload path like (app/models). When Rails sees MyApp::User (in code which is not inside a module definition) it will only look for my_app/user.rb in directories in the autoload path.

You could trick Rails a lot of the time by never using qualified constants. If your controllers are in the same namespace, the following would work:

app/controllers/my_app/users_controller.rb

module MyApp
  class UsersController < ApplicationController
    def index
      @users = User.all
    end
  end
end

app/models/user.rb

module MyApp
  class User < ActiveRecord::Base
  end
end

Rails doesn't know whether the User referenced in the controller is top-level or in MyApp, so it would look for both app/models/user.rb and app/models/my_app/user.rb. Similarly, you could autoload namespaced models in app/models from other namespaced models.

However, you'd hit a wall (that is, you'd have to manually require the model class file) as soon as you needed to refer to a namespaced model from code which was not itself in a namespace, e.g. in the console or in a unit test. And it would be silly to have controllers in a subdirectory but models not in a subdirectory. And you'd be confusing anyone who looked at your code. So the best thing to do would be to follow Rails convention and put your namespaced models in a subdirectory of app/models.

Upvotes: 3

Related Questions