简体   繁体   中英

Rails 3 controller and model subfolders

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM