htafoya
htafoya

Reputation: 19283

Ruby on Rails - Controller Subdirectory

I am somewhat new to RoR,

I want to have a structured directory, because project may become big I don't want to have all controllers directly into controllers directory.

I would want something as

app/
    controllers/
          application_controller.rb
          groupa/
                athing_controller.rb
                athing2_controller.rb
          groupb/
                bthing_controller.rb

However when I place in the routes.rb the following:

get 'athing', :to => "groupa/athing#index"

I get the following error on localhost:3000/athing/ :

superclass mismatch for class AthingController

Which is like:

class AthingController < ApplicationController
  def index
  end
end

Am I missing something? Can I place subdirectories at all?

Upvotes: 8

Views: 8329

Answers (3)

Richard Peck
Richard Peck

Reputation: 76784

Modularity

When you put your controllers (classes) into a subdirectory, Ruby/Rails expects it to subclass from the parent (module):

#app/controllers/group_a/a_thing_controller.rb
class GroupA::AThingController < ApplicationController
  def index
  end
end

#config/routes.rb
get :a_thing, to: "group_a/a_thing#index" #-> url.com/a_thing

I've changed your model / dir names to conform to Ruby snake_case convention:

  • Use snake_case for naming directories, e.g. lib/hello_world/hello_world.rb
  • Use CamelCase for classes and modules, e.g class GroupA

Rails routing has the namespace directive to help:

#config/routes.rb
namespace :group_a do
  resources :a_thing, only: :index #-> url.com/group_a/a_thing
end

... also the module directive:

#config/routes.rb
resources :a_thing, only: :index, module: :group_a #-> url.com/a_thing
scope module: :group_a do
  resources :a_thing, only: :index #->  url.com/a_thing
end

The difference is that namespace creates a subdir in your routes, module just sends the path to the subdir-ed controller.

Both of the above require the GroupA:: superclass on your subdirectory controllers.

Upvotes: 5

Aditya Majeti
Aditya Majeti

Reputation: 41

In config/routes.rb

namespace :namespace_name do
  resources : resource_name
end

In app/controllers/

create a module name with your namespace_name, in that place your controllers In that controller class name should be like class namespace_name::ExampleController < ApplicationController

Upvotes: 3

user5245636
user5245636

Reputation:

Try to use namespace instead:

In your routes:

namespace :groupa do
  get 'athing', :to => "athing#index"
end

In your controller:

class Groupa::AthingController < ApplicationController

In browser:

localhost:3000/groupa/athing/

Upvotes: 16

Related Questions