Lykos Lykos - 2 months ago 19
Ruby Question

Rails - proper way to create admin section (`module` or `Admin::`)?

I'm new in Ruby and RoR and I'd like to create an admin section for a demo app.

From a little research I've done I've found two different options for creating an admin section. Example:

# config/routes.rb
namespace :admin do
resources :users
end

# app/controllers/admin_controller.rb
class AdminController < ApplicationController
before_filter :authorized?
...
end


Which of the two options is the most proper way to define controllers for the admin section, or they are both equally same?

# app/controllers/admin/users_controller.rb

# I think this is what rails generates if I run the "rails g controller admin::users" command
class Admin::UsersController < AdminController
...
end

# or instead
module Admin
class UsersController < AdminController
....
end
end

Answer

Both approaches yield to the same result, which is an UsersController which inherits from AdminController and is found in the Admin module (namespace).

Admin::MyClass is just a shortcut for module Admin ... class MyClass, but...

I would however prefer the explicit nested code (with module Admin on its own line), because it does make a different if the Admin-module has never been defined before. This probably won't happen to you when hacking with standard rails, but can happen when you write ruby code outside of rails.

See these examples:

class I::Am::AClass
end

i = I::Am::AClass.new
puts i.inspect

will lead to

i.rb:1:in `<main>': uninitialized constant I (NameError)

if you never declared the I and nested Am modules before in your code.

Whereas

module I
  module Am
    class AClass
    end
  end
end

i = I::Am::AClass.new
puts i.inspect

will work:

#<I::Am::AClass:0x00000001d79898>

because the modules are created along the path to AClass (at least this is how I think about it).

If you ever run in that problem and want to save whitespaces (because you will usually indent stuff in a module definition), there are some idioms to use. The one that solves the problem in the most obvious way (again, to me) is the following:

# Predefine modules
module I ; module Am ; end ; end
# Just a shortcut for:
# module I
#   module Am
#   end
# end

class I::Am::AClass
end

i = I::Am::AClass.new
puts i.inspect

#<I::Am::AClass:0x000000024194a0>

Just found that the nature of your question (it is not about an Admin-Interface, more about Module-Syntax) is also nicely discussed here Ruby (and Rails) nested module syntax . And I would love to see a ruby-bug report/feature-request on this :)