Hey I am trying to namespace a bunch of controllers that I only want admins to be able to access. For example, I want routes like admin/products or admin/categories, but when I call any of those controllers located in my controllers/admin folder, I get the following error message
superclass mismatch for class CategoriesController
If I restart the server right after, I get this
Unable to autoload constant Admin::CategoriesController
and
Circular dependency detected while autoloading constant Admin::CategoriesController
These are my routes
Rails.application.routes.draw do
root 'pages#home'
devise_for :admins
namespace :admin do
resources :categories, :except => [:new, :show]
resources :products
end
resources :products
resources :carts, :only => [:show]
resources :line_items, :only => [:create, :destroy]
# Shop controller
get 'shop/index
# Admin controller
get 'admin/index'
This is my categories controller
class CategoriesController < ApplicationController
before_filter :authenticate_admin!
def index
#categories = Category.all
#category = Category.new
end
def create
category = Category.new(categories_params)
if category.save
flash[:notice] = "You have added a new category"
redirect_to categories_path
else
flash[:error] = "An error occured"
render "index"
end
end
def edit
#category = Category.find(params[:id])
end
def update
#category = Category.find(params[:id])
if #category.update(categories_params)
flash[:notice] = "Succesfully updated #{#category[:name].titleize}"
redirect_to categories_path
else
flash[:error] = "An error occured trying to update #{#category[:name].titleize}"
render "edit"
end
end
def destroy
#category = Category.find(params[:id])
if #category.destroy
flash[:notice] = "You succesfully removed #{#category.name}"
else
flash[:error] = "An error occured trying to remove #{#category.name}"
end
redirect_to categories_path
end
private
def categories_params
params.require(:category).permit(:name)
end
end
This has been troubling me for some time now so any help will be greatly appreciated
You forgot to namespace the Controller class :
class Admin::CategoriesController < ApplicationController
which is why you receive Unable to autoload constant Admin::CategoriesController error as Rails is looking for namespaced class Admin::CategoriesController and what you have is CategoriesController
Related
I am getting a routing error when I attempt to create a new db entry or update a current one.
ERROR: No route matches [POST] "/pubs"
Routes.rb:
resources :people, except: [:show] do
resources :pubs, except: [:create, :new, :edit, :destroy]
end
resources :articles
resources :pubs, except: [:create, :new, :edit, :destroy]
namespace :sekret do
resources :people do
resources :pubs
end
end
sekret/pubs_controller
class Sekret::PubsController < SekretController
def index
#pubs = Pub.all
end
def show
#pub = Pub.find(params[:id])
end
def new
#person = Person.find(params[:person_id])
#pub = #person.pubs.new
end
def create
#pub = Pub.new(pub_params)
if #pub.save
flash[:notice] = "Article created successfully!"
redirect_to sekret_person_pub_path(#pub)
else
render :new, status: :unprocessable_entity
end
end
def edit
#pub = Pub.find(params[:id])
end
def update
#pub = Pub.find(params[:id])
if #pub.update(pub_params)
redirect_to sekret_person_pub_path(#pub)
else
render :edit, status: :unprocessable_entity
end
end
def destroy
pub = Pub.find(params[:id])
pub.destroy
redirect_to sekret_people_path
end
private
def pub_params
params.require(:pub).permit(
:pubmed_id, :journal, :pages, :date, :type, :link, :authors,
:title, :notes, :auth_id, :person_id)
end
end
After going through all of this setup, when I allow the non-namespace pubs to resolve edit, update, etc, the update process goes through without a hitch. Once I limit these functions to within the password protected namespace I get the routing error. After parsing through the routes I can see that sekret_person_pub_path is listed there. I think I am missing something somewhere.
Rake Routes:
pubs#index
pub GET /pubs/:id(.:format) pubs#show
PATCH /pubs/:id(.:format) pubs#update
PUT /pubs/:id(.:format) pubs#update
sekret_person_pubs GET /sekret/people/:person_id/pubs(.:format) sekret/pubs#index
POST /sekret/people/:person_id/pubs(.:format) sekret/pubs#create
new_sekret_person_pub GET /sekret/people/:person_id/pubs/new(.:format) sekret/pubs#new
edit_sekret_person_pub GET /sekret/people/:person_id/pubs/:id/edit(.:format) sekret/pubs#edit
sekret_person_pub GET /sekret/people/:person_id/pubs/:id(.:format) sekret/pubs#show
PATCH /sekret/people/:person_id/pubs/:id(.:format) sekret/pubs#update
PUT /sekret/people/:person_id/pubs/:id(.:format) sekret/pubs#update
DELETE /sekret/people/:person_id/pubs/:id(.:format) sekret/pubs#destroy
sekret_people GET /sekret/people(.:format)
By using resources :pubs, except: [:create, :new, :edit, :destroy], you are preventing the route generation from providing POST /pubs.
The namespace and nested resources will generate a URL POST sekret/people/:person_id/pubs.
In your controller, you should create the Pub as an associated object.
def create
person = Person.find(params[:person_id])
#pub = person.pubs.new(pub_params)
if #pub.save
flash[:notice] = "Article created successfully!"
redirect_to sekret_person_pub_path(#pub)
else
render :new, status: :unprocessable_entity
end
end
If you want to restrict access the create method, you could use an authorization library such as Pundit in which case you would setup a policy to restrict who can do what.
https://github.com/elabs/pundit
You are missing out on the routes because rails form don't use the correct routes when namespacing so you'll have to specify them manually
<%= form for #pub, url: sekret_person_pubs_path do |f| %>
to let the form knows which route to post, if you do not specify the url, rails will use url: person_pubs_path behind the scenes
Edit: forgot to add _path
I have a SubcategoriesController
class Categories::SubcategoriesController < ApplicationController
def new
#category = Category.find(params[:category_id])
#subcategory = Subcategory.new
end
def edit
end
def create
end
def destroy
end
end
These are my routes
resources :categories do
resources :subcategories, except: [:index, :show]
end
When I'm trying to visit categories_path, it throws uninitialized constant SubcategoriesController
Where did I go wrong?
Current route configuration expects to find SubcategoriesController in app/controllers/subcategories_controller.rb, but you have declared Categories::SubcategoriesController (perhaps in app/controllers/categories/subcategories_controller.rb).
Try moving and renaming the controller so router can find it.
Hope that helps!
I'm building an app which consists on sharing résumés. I am using Devise gem. Each user is able to create only one résumé. I made the models and and their relations. Resume belongs_to User and User has_one 'Resume'.
After making the views, I wanted to test my app but I got the error: undefined methodbuild' for nil:NilClass`
Here is my ResumeController and my routes.rb
class ResumeController < ApplicationController
before_action :find_resume, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:show]
def show
# #resume = Resume.find_by(params[:id])
end
def new
#resume = current_user.resume.build
end
def create
#resume = current_user.resume.build(resume_params)
if #resume.save
redirect_to #resume, notice: "resume was successfully created"
else
render 'new'
end
end
def edit
end
def update
if #resume.update(pin_params)
redirect_to #resume, notice: "resume was successfully updated"
else
render 'edit'
end
end
def destroy
#resume.destroy
redirect_to root_path
end
private
def resume_params
params.require(:resume).permit(:title, :description)
end
def find_resume
#resume = resume.find(params[:id])
end
end
Routes.rb
Rails.application.routes.draw do
devise_for :users
resources :resume, except: [:index]
get 'static_pages/index'
root to: "static_pages#index"
end
I just want the user to be able to create only one Resume and then he will be able to share it.
Update: After following messanjah's answer there was another error coming from the _form.html.erb: undefined method resumes_path' for #<#<Class:0x00...>. Here is the gist with forms and model: goo.gl/XvW2LH So you can see all the files closely.
Without more knowledge of where the error is happening, I can only suggest some areas that might be suspect.
To build a has_one relationship, you must use the build_*association* constructor.
def new
#resume = current_user.build_resume
end
def create
#resume = current_user.build_resume(resume_params)
end
error
uninitialized constant YourSpace::UsersController::User
controller
class YourSpace::UsersController < ApplicationController
def new
#title = YourSpace
end
def edit
#title = YourSpace
#user = User.find(params[:id])
end
def update
name = params[:user][:name]
if name.blank?
flash[:notice] = "Name can not be blank dawg!"
redirect_to :back
else
User.find(params[:id]).update_attributes(params[:user])
# redirect_to :action 'show'
redirect_to :action => :show
# render :action => 'show'
end
end
def index
#title = YourSpace
#users = User.limit(100).order('created_at DESC')
end
def show
#title = YourSpace
#user = User.find(params[:id])
end
end
routes
Rails.application.routes.draw do
root 'site#home'
get '/about', to: 'site#about', as: :about
namespace :your_space do
resources :users
end
namespace :word_cloud do
resources :words, :only => [:index, :create]
end
namespace :word_clock do
resources :page, :only => [:index]
end
namespace :wish do
resources :page, :only => [:index]
end
end
when firing up the rails server, I get error in the YourSpace UsersController where this line of code #users = User.limit(100).order('created_at DESC') is apparently all jacked up. Please know I'm trying to duplicate 180 websites in 365 days which is mostly built using ruby and rails. I'm following closely along the repo to build muscle memory. very much new to learning how to think, and programming.
First thought was wrong.. to solve the problem change User to ::User
My first thought is that you need to put this YourSpace::UsersController in app/controllers/your_space/users_controller.rb. Rails forces directory structure.
I get an error when I try to visit the below url in my rails app.
http://localhost:3000/origtexts/1/reviews/new
routes.rb
resources :origtexts do
resources :reviews
end
It passes the param of the review (1) correctly but I the error I get is undefined method `review' for the line in ReviewsController#new.
reviews_controller.rb
class ReviewsController < ApplicationController
before_filter :find_origtext
before_filter :find_review, :only => [:show, :edit, :update, :destroy]
def new
#review = #origtext.review.build
end
def show
end
def create
#review = #origtext.reviews.build(params[:review])
if #review.save
flash[:notice] = 'Review has been created'
redirect_to [#origtext, #review]
else
flash[:alert] = 'Review has not been created'
render :action => 'new'
end
end
private
def find_origtext
#origtext = Origtext.find(params[:origtext_id])
end
def find_review
#review = #origtext.reviews.find(params[:id])
end
end
Any advice on how to fix this?
Change review to reviews in this line
#review = #origtext.review.build
To
#review = #origtext.reviews.build