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
Related
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.
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.
SingularI have this problem. I defined in route file my route:
namespace :admin do
root to: "home#index"
resources :define_user
end
I created users controller:
class DefineUsersController < ApplicationController
def create
...
end
def destroy
...
end
end
I created in views new folder 'define_users' with file 'show.html.haml'. I call it using link_to:
=link_to 'User', admin_define_user_path
And I get above error. I would like to stay with singular name. Thank for all answers.
You are trying to access show route without id of DefineUser object
= link_to 'User', admin_define_user_path(define_user)
Where define_user is an object of DefineUser class or id of this object
First of all, if you want to link_to some define_user, you have to provide object or id. Something like this: admin_define_user_path(#define_user).
To display all possible routes type rake routes in console.
Also resources should be in plural form.
Moreover you have to provide namespace in controller.
P.S.
As I see, it is a very bad idea to work with model called DefineUser. It's not a rails way. Just use User. DefineUser is a good name for method, but not model.
So, the best idea to handle your code:
routes.rb
namespace :admin do
root to: "home#index"
resources :users
end
users_controller.rb
class Admin::UsersController < ApplicationController
def index
...
end
end
view
= link_to 'Users', admin_users_path # for index
= link_to 'User', admin_user_path(#user) # for one user
Good idea to separate controllers by namespace. For example, you can have next structure:
application_controller.rb
admin #folder
L base_controller.rb
L users_controller.rb
L ..._controller.rb
So your base_controller should be inherited from application_controller
class Admin::BaseController < ApplicationController
layout 'admin_layout' # Different layout for all admin pages
Other controller in admin namespace will be inherited from base_controller
class Admin::UsersController < Admin::BaseController
def create
...
end
I have trouble creating a module for my controller, and getting my routes to point to that module within the controller.
Getting this error:
Routing Error
uninitialized constant Api::Fb
So, this is how my routes are set up:
namespace :api do
namespace :fb do
post :login
resources :my_lists do
resources :my_wishes
end
end
end
In my fb_controller i want to include modules that will give me paths like this:
/api/fb/my_lists
This is some of my fb_controller:
class Api::FbController < ApplicationController
skip_before_filter :authenticate_user!, :only => [:login]
include MyLists # <-- This is where i want to include the /my_lists
# namespace(currently not working, and gives me error
# mentioned above)
def login
#loads of logic
end
end
The MyLists.rb file(where i define a module) is in the same directory as the fb_controller.rb.
How can i get the namespacing to point to my module inside of the fb_controller, like /api/fb/my_lists ?
The namespace you have set up is looking for a controller class that looks like this
class Api::Fb::MyListsController
If you want to have a route that looks like /api/fb/my_lists but you want to still use the FbController instead of having a MyListsController you need to set up your routes to look like this
namespace :api do
scope "/fb" do
resources :my_lists, :controller => 'fb'
end
end
In my opinion, instead of including a module MyLists in your FbController seems kind of awkward.
What I would probably do is have a module FB with a generic FbController then have MyListsController < FbController. Anyway, this is beyond the scope of your question.
The above should answer for your needs.
EDIT
From your comments, and my assumptions on what you're trying to do this is a small example:
config/routes.rb
namespace :api do
scope "/fb" do
post "login" => "fb#login"
# some fb controller specific routes
resources :my_lists
end
end
api/fb/fb_controller.rb
class Api::FbController < ApiController
# some facebook specific logic like authorization and such.
def login
end
end
api/fb/my_lists_controller.rb
class Api::MyListsController < Api::FbController
def create
# Here the controller should gather the parameters and call the model's create
end
end
Now, if all you want to create a MyList Object then you could just do the logic directly to the model. If, on the other hand, you want to handle some more logic you'd want to put that logic in a Service Object that handles the creation of a MyList and its associated Wishes or your MyList model. I would probably go for the Service Object though. Do note, the service object should be a class and not a module.
In your example, Fb isn't a namespace, it's a controller. The namespace call is forcing your app to look for a Fb module that doesn't exist. Try setting up your routes like this:
namespace :api do
resource :fb do
post :login
resources :my_lists do
resources :my_wishes
end
end
end
You can optionally define a new base controller for the API namespace:
# app/controllers/api/base_controller.rb
class Api::BaseController < ApplicationController
end
If you do so, your other controllers can inherit from this:
# app/controllers/api/fb_controller.rb
class Api::FbController < Api::BaseController
end
Running rake routes should give you an idea of how your other controllers are laid out. Just a warning - it's generally not recommended to have resources nested more than 1 deep (you're going to end up with complex paths like edit_api_fb_my_list_my_wish_path). If you can architect this in a simpler way, you'll probably have an easier time of this.
Playing with Rails and controller inheritance.
I've created a controller called AdminController, with a child class called admin_user_controller placed in /app/controllers/admin/admin_user_controller.rb
This is my routes.rb
namespace :admin do
resources :admin_user # Have the admin manage them here.
end
app/controllers/admin/admin_user_controller.rb
class AdminUserController < AdminController
def index
#users = User.all
end
end
app/controllers/admin_controller.rb
class AdminController < ApplicationController
end
I have a user model which I will want to edit with admin privileges.
When I try to connect to: http://localhost:3000/admin/admin_user/
I receive this error:
superclass mismatch for class AdminUserController
This error shows up if you define two times the same class with different superclasses. Maybe try grepping class AdminUserController in your code so you're sure you're not defining it two times. Chances are there is a conflict with a file generated by Rails.
To complete what #Intrepidd said, you can wrap your class inside a module, so that the AdminUserController class doesn't inherit twice from ApplicationController, so a simple workaround would be :
module Admin
class AdminUserController < AdminController
def index
#users = User.all
end
end
end
I fixed it by creating a "Dashboard" controller and an "index" def. I then edited my routes.rb thusly:
Rails.application.routes.draw do
namespace :admin do
get '', to: 'dashboard#index', as: '/'
resources :posts
end
end