Getting an "uninitialized constant" error. I am trying to make a "AdminCotroller"(subcontroller) to the ApplicationController to control one area of the website (the "admin" area).
The routing seems to be correctly set up. I attach 2 things (both from: app/controller/admin/ folder) which produce the error:
1) the "parent" controller
class Admin::AdminController < ApplicationController
layout "admin/layout"
end
2) the "child" controller
class Admin::ProductsController < Admin::AdminController
PS: I wanted to make a separate layout and this was the only solution I could think off.
PPS: Folder Structure
Check the above file structure, that's what I have used.
And controllers as below:
class Admin::BaseController < ApplicationController
layout 'admin'
...
end
class Admin::AdminUsersController < Admin::BaseController
...
end
I don't know what I messed up those days. I haven't tried a given answer but instead I found a workable solution for naming I would like to share:
module Admin
class UsersController < BaseController
...
end
end
this way you achieve a namespace in a folder "admin" too.
Related
I have little problem about my code I make controller/admin/moderators_controller.rb.
I got an error on compilator uninitialized constant Admin (NameError) in moderators_controller.rb.
In navigator I got this error:
superclass must be a Class (Module given)
navigator error
class Admin::ModeratorsController < ActionController
def index
end
end
This is my routes.rb file:
Rails.application.routes.draw do
namespace :admin do
resources :moderators, only: [:index]
end
end
You’ve accidentally made your controller inherit from ActionController (a module) instead of ActionController::Base (a class). You need to add ::Base to the end there.
If this is Rails 5, the common convention now is to have a ApplicationController class in your app/controllers folder, and have all controllers inherit from that (it’s just a class that inherits from ActionController::Base, but gives you a place to put common methods).
Rails 5
class Admin::ModeratorsController < ApplicationController
def index
end
end
Rails 4 or below
class Admin::ModeratorsController < ActionController::Base
def index
end
end
I'm trying have a different frontend and backend view for certain parts of my app, starting with Users.
I'm getting the error uninitialized constant Office::DashboardController, which I understand means it can't find the controller? I feel like it's an issue with how I've setup the namespace / directories, but I can't seem to work it.
routes.rb
namespace :office do
root to: "dashboard#index"
resources :users
end
office/dashboards_controller.rb
class Office::DashboardsController < ApplicationController
layout "office"
end
office/users_controller.rb
class UsersController < Office::DashboardController
def index
#users = User.all
end
def show
#user = User.find_by_username(params[:id])
end
end
There is a chance I've completely messed this up and it's totally wrong...if that's the case, I would love some feedback!
Many thanks in advance :)
You have DashboardController inside Office module, but UsersController isn't in the module. Why is that? Both of them are in the same folder.
So, either
class Office::UsersController < Office::DashboardController
or
module Office
class UsersController < DashboardController
should work as expected.
Tip: you can run rails routes and see folders/class names Rails expects.
I'm having trouble starting to build my own admin section. I get this error when trying to view example.com/admin:
TypeError in Admin::AdminController#dashboard
"superclass mismatch for class AdminController"
My admin controller is in app/controllers/admin/admin_controller.rb
Here is my routes.rb:
Rails.application.routes.draw do
namespace :admin do
root :to => "admin#dashboard"
resources :posts
end
Here is my AdminController:
class AdminController < ApplicationController
def dashboard
print "Dashboard"
end
end
My plan is to have example.com/admin go to the admin dashboard. To edit/create posts: /admin/posts.
You already have a Admin::AdminController class defined elsewhere. Which inherits from different class other then ApplicationController
If you have not created a second Admin::AdminController class yourself, it is likely one of your Gems or plugins already defines it.
If you are using active_admin or rails_admin gem , maybe it does have class with the above name AdminController
You can cross check by replacing the AdminController with some other name maybe AdminController2
Given the following controller structure:
# application_controller.rb
class ApplicationController < ActiveController::Base; end
# pages_controller.rb
class PagesController < ApplicationController; end
# admin/application_controller.rb
module Admin
class ApplicationController < ::ApplicationController; end
end
# admin/pages_controller.rb
module Admin
class PagesController < ApplicationController; end
end
One would expect Admin::PagesController to inherit from Admin::ApplicationController and it does. But I have noticed that sometimes it inherits from ::ApplicationController.
So I decided not to risk it and changed declaration of all controllers in /admin to specifically target Admin::ApplicationController
# admin/pages_controller.rb
module Admin
class PagesController < Admin::ApplicationController; end
end
Okay that works, but from what I know it was correct in the first place. Why Rails inherits from a wrong controller sometimes?
Admin::PagesController sometimes inherits from ApplicationController instead of Admin::ApplicationController despite both being in the same module Admin
The problem here is rails' development mode code loading: in general code is loaded when you try to do something with a constant (eg subclass from it) and that constant doesn't exist. This results in const_missing being called and rails uses it this to try to load the class (for a detailed description see the guide).
If neither ApplicationController nor Admin::ApplicationController exist then when you access your admin pages controller ruby will hit that const_missing and try to load admin/application_controller.rb
However if ApplicationController is already loaded then ruby won't fire const_missing since it perfectly legal for a class in the admin module to inherit from something at the toplevel.
The solution as you say is to make explicit what you are inheriting from. Personally in my own apps I use Admin::BaseController as the base class.
Another option is to use require_dependency to point Rails to the correct file:
# admin/application_controller.rb
require_dependency 'admin/application_controller'
module Admin
class PagesController < ApplicationController
end
end
I have the following setup:
class UsersController < ApplicationController
...
end
class Admin::BaseController < ApplicationController
...
end
class Admin::UsersController < Admin::BaseController
...
end
And likewise specs:
#spec/controllers/users_controller_spec.rb:
describe UsersController do
...
end
#spec/controllers/admin/users_controller_spec.rb
describe Admin::UsersController do
...
end
All the specs run fine when run independantly, however when I run all together I get the warning:
toplevel constant UsersController referenced by Admin::UsersController
And the specs from the admin controller don't pass.
Routes file:
...
resources :users
namespace "admin" do
resources :users
end
...
Rails 4, Rspec 2.14
Can I not use the same name for controllers in different namespaces?
This happens when a top level class get autoloaded before a namespaced one is used. If you have this code without any class preloaded :
UsersController
module AdminArea
UsersController
end
The first line will trigger constant missing hook : "ok, UsersController does not exist, so let's try to load it".
But then, reaching the second line, UsersController is indeed already defined, at top level. So, there's no const_missing hook triggered, and app will try to use the known constant.
To avoid that, explicitly require proper classes on top of your spec files :
#spec/controllers/users_controller_spec.rb:
require 'users_controller'
And
#spec/controllers/admin/users_controller_spec.rb
require 'admin/users_controller'