Reputation: 103
I am writing a Rails 3.2.6 app. I want to separate my controllers and models into subfolders to keep my code clean. I have ensured that the model and its subdirectory name are not the same. However, I find that the code fails if the controller subdirectory name and the model subdirectory name are the same.
The following application structure works fine:
test
app
controllers
postcnt
posts_controller.rb
models
postmdl
post.rb
but the following structure doesn't:
test
app
controllers
postnsp
posts_controller.rb
models
postnsp
post.rb
When I call the URL:
http://localhost:3000/postnsp/posts
I get a 500 error with the message:
LoadError in Postnsp::PostsController#index
Expected /Users/dev/code/test/app/models/postnsp/post.rb to define Postnsp::Post
In the above examples I followed the advice here to eliminate model namespacing: Rails: Elegant way to structure models into subfolders without creating submodules
and added
config.autoload_paths += Dir[Rails.root.join('app', 'models', '{**}')]
to my application.rb file
For the second (failing) example the relevant files are as follows:
post.rb:
class Post < ActiveRecord::Base
attr_accessible :content, :name
end
posts_controller.rb:
class Postnsp::PostsController < ApplicationController
def index
@posts = Post.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: @posts }
end
end
routes.rb:
Test::Application.routes.draw do
namespace :postnsp do resources :posts end
Can anyone explain why the subdirectories can't be the same? I assume it's something to do with the creation of the postnsp module for the posts_controller.rb but I can't understand why it's preventing the creation of the model. I would like to have consistency in the directory structure naming in both the controller and model folders should I require it.
Upvotes: 1
Views: 2494
Reputation: 3815
Since Post
is in the postnsp
directory, it expects the model to also be scoped by the namespace.
Try changing your Post
to Postnsp::Post < ActiveRecord::Base
UPDATE
Okay, I tried an app to do exactly what you told, and I think I know what's wrong...
Since you're inside a namespaced controller, when you use Post
it actually looks for Postnsp::Post
, in order to use the base class you must use ::Post
and then everything worked for me.
Hope this helps.
Upvotes: 1