@madpilot makes

Sub-directories on rails

I haven’t been able to find this anywhere in literature (I’m sure it is somewhere, I just haven’t figured a good enough google search string to find it), but I wanted to be able to use sub directories to partition different areas in Ruby on Rails.

e.g /admin /admin/articles etc

Ruby on rails uses the following mappings between the URL and the controller:

http://www.url.com/application/controller/action/id

which maps to a AcitonController class called controller which has a method called action

I wanted to have multiple a controller directories:

http://www.url.com/application/controller/subcontroller/action/id

You do this by creating a sub directory under the controller directory (in this case called controller) and creating file called subcontroller_controller.rb – The class declaration of this file should be Controller::SubControllerController < ApplicationController.

 

So, if you wanted to create a controller called articles in the sub directory admin you would create:

  1. The subdirectory “admin” under the controllers directory
  2. The file articles_controller.rb in the controllers/admin directory
  3. Declare the class as: Admin::ArticlesController < ApplicationController

You also need to create the corresponding .rhtml files in a sub directory in the views folder…

10 comments

  1. Very helpful post; thank you.



    Just one question though, have you been able to get a controller working from just within the "admin" folder? As well as having the sub-controllers.

    I'm having some serious trouble, the admin controller takes over and tries to find actions with the names of the sub-controllers.
  2. Just to check we are talking about the same thing:



    You want to have a controller called admin AND controllers under the admin directory?



    Try playing with the routes.rb file. I did a quick test on one of my projects by creating an admin_controller.rb with an index action and had the same problem that you did.



    One of the admin sub-controllers in that project has a modified map.connect command in the routes.rb file and it worked ok. Note though that I couldn't get



    map.connect 'admin/:controller/:action/:id'



    to work. Admittedly I didn't look that closely.



    Hope that helps :)
  3. There's a problem with this method-- the problem is that when you have a model of the same name as your controller sub-directory, it will cause a namespace conflict

    eg. model with name Admin and controller under admin/Articles



    There is a solution which I came close to, but I can't really get it, and it's naming the sub-directory as admin_controller/ and putting the files in there (That would change the name to AdminController::ArticlesController). This would clear the namespace issues, and apparently Rails will still recognize the path as /admin/articles ...HOWEVER, it error's up with other issues, so it's not really working. basically, I don't know why the routing is recognizing it, it's either a bug or a feature, and i can't tell
  4. hey, thanks for the help on this one. i was wanting to do exactly what you explained here and google sent me right to you. a life saver, that's what you are.



    i'm a ruby on rails baby, but i LOVE it so far...



    eli
  5. This seems to be broken in Rails 1.1 can anyone confirm?
  6. I'm using Rails 1.2 and it seems to be working ok
  7. Without your post I'd have never figured out how to do the subcontrollers. I do have the same problem as the first comment though - no amount of routing-fu will make Rails know the difference between "admin/services" (controller/action) and "admin/services" (directory/subcontroller). I'm wondering if it's possible to put in stub actions in the top-level admin_controller.rb that have the same name as the subcontrollers and just redirect to them?



    And if it is possible, is it bad coding practice?
  8. I've tried various ways of redirecting, and they are all snafu'd because no matter what you do, if there is a top-level controller with the same name as the directory holding the subcontroller the next section will be interpreted to be an action. This spirals around until the stack is full.



    It's not as pretty, but I guess I can have one master 'admin' controller redirecting to numerous 'admin_foo' subcontrollers, and just not use the subdir trick. It presents a slightly less consistent interface to the client, but it works.
  9. Turns out that a Ruby-On-Rails Forum posting by a user "tdog" answers this question:



    http://www.rubyonrailsforum.com/rails-code-questions/54-controller-subdirectories-directory-mapping.html





    Summary is here:



    Suppose you already have a controller FOO, and you want to add a new controller FOO/BAR



    In routes.rb, you should add the folowing:





    Code:



    map.connect 'FOO/BAR/:action/:id', :controller => "FOO/BAR"





    OR, this works for a single "index.html" view within the controller FOO/BAR



    map.connect 'FOO/BAR/:action', :controller => "FOO/BAR"





    -- John Wolfe
  10. One more thing - the "./script/generate Controller FOO/BAR index" command from my previous post will NOT generate a



    app/views/layouts/FOO/bar.rhtml



    file, so if you want your own layout file, you will have to create the subdirectory within the app/views/layouts directory.



    -- John Wolfe

Leave a comment