Uninitialized Constant Error in Nested Controller - ruby-on-rails

I am getting this error:
Routing Error
uninitialized constant RegistrationsController
This is my log:
Started GET "/registrants/1/registrations/new" for 127.0.0.1 at 2012-07-03 00:55:44 -0500
ActionController::RoutingError (uninitialized constant RegistrationsController):
Rendered /.rvm/gems/ruby-1.9.2-p0/gems/actionpack-3.1.3/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (8.5ms)
This is the part of my routes.rb that is appropriate:
registrant_registrations GET /registrants/:registrant_id/registrations(.:format) {:action=>"index", :controller=>"registrations"}
POST /registrants/:registrant_id/registrations(.:format) {:action=>"create", :controller=>"registrations"}
new_registrant_registration GET /registrants/:registrant_id/registrations/new(.:format) {:action=>"new", :controller=>"registrations"}
edit_registrant_registration GET /registrants/:registrant_id/registrations/:id/edit(.:format) {:action=>"edit", :controller=>"registrations"}
registrant_registration GET /registrants/:registrant_id/registrations/:id(.:format) {:action=>"show", :controller=>"registrations"}
PUT /registrants/:registrant_id/registrations/:id(.:format) {:action=>"update", :controller=>"registrations"}
This is my Registrations Controller, which is at /app/controllers/portal/registrations_controller.rb:
class Portal::RegistrationsController < ApplicationController
def create
#registrant = current_member.registrants.find(params[:registrant])
#registration = #registrant.registrations.build
respond_to do |format|
if #registration.save
format.html { redirect_to root_path, :notice => "Registration successfully created!" }
format.json { head :ok }
else
format.html { redirect_to root_path, :notice => "There was a problem with the registration." }
end
end
end
end
I get this error when I call new_registrant_registration_path(registrant) from a view in Portal#index.
Edit:
For completeness, here is my routes.rb file in its entirety before the solution was found. Radar mentioned the gist I posted, but I figured I would put the code here in case that gist is deleted.
MyApp::Application.routes.draw do
match 'admin' => 'admin/dashboard#index', :as => :admin_root
match 'portal' => 'portal#index', :as => :member_root
namespace 'admin' do
match 'profile' => 'profile#show', :as => :profile
resources :members
resources :admins
resources :packages
resources :products
resources :levels
resources :lessons
resources :registrations
resources :registrants, :controller => 'customers/registrants'
resources :locations
resources :schools
resources :terms
resources :customers
resources :invoices
resources :payments
end
namespace 'member' do
resources :registrations
end
match 'register' => 'member/registrations#new', :as => :signup
match 'login' => 'member_sessions#new', :as => :login
match 'logout' => 'member_sessions#destroy', :as => :logout
match 'admin/login' => 'admin_sessions#new', :as => :admin_login
match 'admin/logout' => 'admin_sessions#destroy', :as => :admin_logout
match 'member/activate/:activation_code' => 'member/activations#create', :as => :member_activation
match 'member/:id/activate/resend' => 'member/activations#resend', :as => :resend_member_activation
match 'member/:id/activate' => 'member/activations#new', :as => :new_member_activation
match 'member/password/reset/begin' => 'member/password_resets#new', :as => :new_member_password_reset, :via => :get
match 'member/password/reset' => 'member/password_resets#create', :as => :member_password_resets, :via => :post
match 'member/password/:token/finish' => 'member/password_resets#edit', :as => :edit_member_password_reset, :via => :get
match 'member/password/reset' => 'member/password_resets#update', :as => :member_password_reset, :via => :put
match 'admin/packages/new/:partial' => 'admin/packages#new'
resources :admins
resources :registrants, :controller => 'portal/registrants' do
resources :registrations
end
resource :admin_session
resource :member_session
root :to => 'portal#index'
end

To make things clear: marcamillion came into #rubyonrails and Freenode and shared his config/routes.rb. That's where I figured out the error that he was making and then figured out the answer.
Two things.
First: Admin root route
Rather than defining the root route for your admin namespace like this:
match 'admin' => 'admin/dashboard#index', :as => :admin_root
Define it inside the namespace :admin call like this:
namespace 'admin' do
root :to => "dashboard#index"
end
This will automatically define it as admin_root_path and admin_root_url, so you won't need to do that, and it will automatically prefix the controller with the admin/ prefix, so you won't need to do that either.
Second: Referencing RegistrantsController
You have this currently in your config/routes.rb:
resources :registrants, :controller => 'portal/registrants' do
resources :registrations
end
What this will do is define resources routes for registrants correctly using the Portal::RegistrantsController, but won't define the nested routes underneath this using Portal::RegistrationsController. What it will do is attempt to use RegistrationsController, which is why you're getting that error.
To fix this, I'd recommend you use the scope method, like this:
scope :module => Portal do
resources :registrants do
resources :registrations
end
end
The scope method, when used in this way, will tell Rails that the controllers for the routes inside the block are under the Portal namespace. This means that it will know that resources :registrants is for Portal::Registrants and that resources :registrations is for Portal::Registrations, thereby fixing the error that you're seeing.

What if you change this line:
class Portal::RegistrationsController < ApplicationController
to:
class RegistrationsController < ApplicationController
?

This is strange. I think, your controller should be located at /app/controllers/registrants/registrations_controller.rb and looks like this:
class Registrants::RegistrationsController < Registrants::ApplicationController
def create
#registration = registrant.registrations.build
...
end
end
class Registrants::ApplicationController < ApplicationController
def registrant
current_member.registrants.find(params[:registrant_id])
end
end
Registrants::ApplicationController (/app/controllers/registrants/application_controller.rb) controller aim is to avoid code duplication.

Related

Error trying to logout: Couldn't find User with 'id'=sign_out

I'm getting this error when I try to logout an user. I checked many posts of this same error but no one solved my error, I hope you can help me.
The error is as follows:
ActiveRecord::RecordNotFound in UsersController#destroy
Couldn't find User with 'id'=sign_out
The following is my code:
users_controller.rb
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to unauthenticated_root_path }
format.json { head :no_content }
end
end
private
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find(params[:id])
end
view/users/index.html.erb
<li>
<%= link_to "Logout", destroy_user_session_path, :method => :delete %>
</li>
routes.rb
Rails.application.routes.draw do
get 'admin/index'
resources :contacts
resources :afections
resources :injuries
resources :allergies
resources :trainers
resources :idusuarios
resources :diseases
resources :weights
resources :diets
resources :exercices
resources :profiles
resources :users
devise_for :users
get '/users/sign_out' => 'devise/sessions#destroy'
devise_scope :user do
authenticated :user do
root 'pagina#index', as: :authenticated_root
end
unauthenticated do
root 'devise/sessions#new', as: :unauthenticated_root
end
end
end
move get '/users/sign_out' => 'devise/sessions#destroy' above resources :users in your routes. Routes are given priority in terms of their order in the routes file.
When you use resources :users in your routes, you have this routes:
/users
/users/:id
/users/:id/edit
and ...
So when /users/sign_out is called, , thinks the sign_out is an ID.
so change /users/sign_out to /user/sign_out for example.
BUT
if you want customize your session paths, you can do this:
customize your session paths:
as :user do
get 'user/signin' => 'devise/sessions#new', :as => :new_user_session
post 'user/signin' => 'devise/sessions#create', :as => :user_session
delete 'user/signout' => 'devise/sessions#destroy', :as => :destroy_user_session, via: [:delete, :get]
end
and skip session in devise:
devise_for :users, :skip => [:sessions]
if you want user registration, you must skip it in devise and then can use user scaffold:
as :user do
get 'user/signin' => 'devise/sessions#new', :as => :new_user_session
post 'user/signin' => 'devise/sessions#create', :as => :user_session
delete 'user/signout' => 'devise/sessions#destroy', :as => :destroy_user_session, via: [:delete, :get]
end
scope "admin" do
resources :users
devise_for :users, :skip => [:sessions, :registrations]
end

Devise routing error: "Unknown action -- The action 'create' could not be found for UsersController"

My devise set up was working fine before, but now, for some reason, whenever I try to sign up a new user, it tries to call users#create instead of registrations#create. I think it must be a problem with my routes.rb file. I recently added a new resource, "preferences", to my application, so the routing might be wonky:
Indexer2::Application.routes.draw do
resources :preferences
get "home/index"
resources :posts
resources :users
devise_for :users, :controllers => {:registrations => 'registrations', :invitations => 'invitations'}, :except => [:show] do
get "/signup" => "devise/registrations#new", :as => 'user_signup'
get '/logout' => 'devise/sessions#destroy', :as => 'user_logout'
get '/login' => "devise/sessions#new", :as => 'user_login'
end
match '/welcome' => 'pages#welcome'
resources :preferences, :except => [:destory, :edit, :create, :new, :index, :show] do
collection do
post "make_feed_preference"
post "change_preference"
end
end
root :to => "home#index"
end
Your UsersController should have create method.
If you don't want to write your own registration logic just do inheritance from Devise::RegistrationsController < DeviseController:
controller UsersController < Devise::RegistrationsController
#....
end
This will include default Devise methods.

Unable To Access Public Images Possible Routing Issue

I'm working on a project and trying to render some images sitting under the public directory in one of my show views. I'm able to access these images just fine on my index view, but it's not quite so easy for show views it would seem.
So lets say in my view I have something like the following:
<%= "<img src=\"images/16x16/actions/filesave.png\" class=\"icon" title=\"save\">"%>
This would work in my index view perfectly fine, but for some strange reason I get this routing error in my show view:
ActionController::RoutingError (No route matches [GET]
"/uploads/images/16x16/actions/filesave.png"):
I noticed that for some peculiar reason it's injecting the "/uploads/" route right before the "/images..." this is the cause of my problem and I can't figure out why or how to stop it. This only happens with my show views.
Now there's a lot going on in my routes.rb file, I know it's ugly but I do plan on going in there and cleaning it up when I get the chance.
resources :upload_images
get "upload_image/new"
get "upload_image/index"
get "upload_image/show"
get "upload_image/delete"
resources :help_categories
resources :global_configs
resources :competitions
match '/teams/register', :controller => 'teams', :action => 'register'
match '/teams/invite_users', :controller => 'teams', :action => 'invite_users'
match '/teams/view_invitations', :controller => 'teams', :action => 'view_invitations'
match '/teams/ignore', :controller => 'teams', :action => 'ignore'
match '/teams/leave_team', :controller => 'teams', :action => 'leave_team'
resources :teams
resources :competitions do
resources :matches
end
resources :registers
resources :players do
collection do
post :edit_individual
put :update_individual
get :results
end
end
resources :tournaments
resources :matches
resources :upload_categories
resources :uploads, :except => [:new]
match '/download/:id' => 'uploads#download'
devise_for :users do
match 'logout' => 'devise/sessions#destroy'
end
resources :users, :except => [:new] do
member do
get 'upload_files'
get 'delete_files'
end
end
resources :games
devise_for :videolinks
resources :topics do
collection do
get "mark_all_viewed"
end
member do
get 'show_new'
end
end
resources :posts do
member do
get 'quote'
get 'topic'
end
end
resources :forums do
member do
get 'confirm_delete'
end
end
resources :blog_entries, :except => [:index]
resources :categories
resources :videolinks
resources :competition_games
resources :competitions
resources :news
resources :events
match 'uploads/find_uploads' => 'uploads#find_uploads'
match 'uploads/add_upload_image' => 'uploads#add_upload_image'
match 'forum_root' => 'forums#index'
match 'upload_root' => 'uploads#index'
match 'user' => 'forums#index'
match 'news_root' => 'news#index'
match 'topic_post' => 'forums#index'
match 'quote_post' => 'forums#index'
match 'new_upload' => 'forums#index'
match 'videolinks/:id', :to => 'videolinks#show'
match 'register' => 'users#sign_up'
match 'login' => 'users#sign_in'
match 'users/find_users' => 'users#find_users'
match '/users/get_states/:country' => 'users#states'
match '/ban/:username' => 'users#ban'
match '/ban_user/:username' => 'users#ban_user'
match ':username' => 'users#show'
match ':username/edit' => 'users#edit'
match ':username/delete_files_all' => 'uploads#index'
match ':username/delete_files' => 'users#delete_files'
match ':username/upload_files' => 'users#upload_files'
match ':username/password/edit' => 'users#editpass'
match ':username/edit_file/:id' => 'uploads#edit'
match '/maketakeadmin/:username' => 'users#maketakeadmin'
match ':username/destroy' => 'users#destroy'
root :to => "home#index"
resources :categories do
member do
get 'confirm_delete'
end
end
Another developer worked on the upload section of this application and it uses paperclip. By default it saves uploads in the public directory and we didn't want that so he told me he did some weird hotfix to save uploads to a private directory off of the root of the application called "uploads". Not sure if this might have anything to do with it.
Needed a forward slash at the start of the path.
I think you should use something like this:
<%= image_tag "/images/16x16/actions/filesave.png", class: "icon", alt: "save" %>

Rails 3.1 subdomain based controller routing

I'm currently getting the error:
No route matches [GET] "/tenant_admin"
I was using something like:
http://example.com/accounts/1/tenant_admin
but I'm now passing the account id as a subdomain;
http://AccountName.example.com/
Is it possible to make the url work like this:
http://AccountName.example.com/tenant_admin ?
Routes.rb
get "log_out" => "sessions#destroy", :as => "log_out"
get "log_in" => "sessions#new", :as => "log_in"
get "sign_up" => "users#new", :as => "sign_up"
resources :users
resources :sessions
resources :password_resets
resources :accounts do
resources :tenant_admin
end
constraints(Subdomain) do
match '/' => 'accounts#show'
end
root :to => "welcome#index"
You have to put your tenant routes under resources :accounts and constraints(Subdomain). I don't recommend using copy and paste but a lambda instead.
tenant_routes = lambda do
resources :tenant_admin
end
resources :accounts do
tenant_routes.call
end
constraints(Subdomain) do
tenant_routes.call
end

Upgrading to Rails 3: Problem with routes

I have a problem to upgrade my routes.rb file.
I converted this route:
map.resource :index, :controller => "users", :action => "index"
By
resource :index, :to => "users#index"
There is no error raised but the page does not display correctly.
Does anyone have an idea?
Update:
I have this instruction:
resources :users
Here is my routes.rb file:
JNetExams::Application.routes.draw do |map|
match 'login', :to => 'user_sessions#new', :as => 'login'
match 'logout', :to => 'user_sessions#destroy', :as => 'logout'
root :to => 'user_sessions#new'
resources :groups
resources :students
resources :users
resources :responses
#map.resource :index, :controller => "users", :action => "index"
resource :index, :to => "users#index"
map.resource :account, :controller => "users"
#resource :account, :controller => "users"
resource :user_session
resource :student
resource :user
map.resource :professor, :controller => "professors", :action => "index"
#resource :professor, :to => "professors#index"
map.connect ':controller/:action/:id'
#match ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
#match ':controller/:action/:id.:format'
#map.connect '*url', :controller => :users, :action => :index
match '*url', :to => "users#index"
#map.connect '/user_sessions/show', :controller => "user_sessions", :action => "show"
match '/user_sessions/show', :to => "user_sessions#show"
How can I upgrade this routes file to Rails 3?
resources :index provides paths for an index resource. So new_index_path will point to the new action in the IndexController. If you do not have an index resource, you should not be using resources to define a path to "users#index". This path is already given to you as users_path through resources :users. If you are looking to set an index page for your application, you can achieve that using root :to => "users#index".
The problem of things not displaying correctly is vague and I employ you to throw more light on that. We are here to help after all.
Do you have a resource called index?
This looks more like it should be
resources :users
If you need more help, please show the whole routes file.

Resources