uninitialized constant error in rails 3 on newly created controller - ruby-on-rails

I added a Session controller to my application for user sign-in / sign-out, using
rails g controller Session new create destroy
then add the following lines to my route file:
resources :sessions, :only => [:new, :create, :destroy]
match '/signup', :to => 'users#new'
match '/signin', :to => 'sessions#new'
match '/signout', :to => 'sessions#destroy'
when I do rake routes in the console, the routes do show up, but when I launch the app in the browser, I got this error:
uninitialized constant SessionsController
Thanks in advance!

You created a Session controller, not a Sessions controller. Since it's singular, you want a singular route:
resource :session, :only => [:new, :create, :destroy]

I was running into this today, and found I had to do three things, 1) use resource (not resources); 2) supply the controller manually, and 3) manually set the url in form_for tags using the resource (may not apply for your case)...
# routes.rb
resource :session, :only => [:new, :create, :destroy], :controller => 'session'
#.../new.html.erb
<% form_for #session, :url => session_path do |f| %>
Specifying the controller matters if, like me, your controller name, file names, etc, are all singular.
This is apparently related to a bug in rails

Related

Undefined method or local variable in rails

undefined local variable or method `requestuser_path' for #<#<Class:0x007f92de073e10>:0x007f92e191a020>
I don't know why this error occurs even though I route to the required controller and the view is also no problem here.
# routes.rb
resources :users do
member do
get :following, :followers
end
end
resources :sessions, only: [:new, :create, :destroy]
resources :microposts, only: [:create, :destroy]
resources :relationships, only: [:create, :destroy]
#resources :requests, only: [:create]
root to: 'static_pages#home'
match '/signup', to: 'users#new'
match '/signin', to: 'sessions#new'
match '/signout', to: 'sessions#destroy', via: :delete
match '/help', to: 'static_pages#help'
match '/about', to: 'static_pages#about'
match '/request', to: 'users#requestuser'
The named route:
<% if signed_in? %>
<li><%= link_to "Requests", requestuser_path %></li>
<% end %>
UsersController:
def requestuser
#title = "Requests"
#user = User.find(params[:id])
#users = #user.followed_users.paginate(page: params[:page])
end
I think there is an error in the named route as I am new to Rails. I don't know what is the cause of error. The named route is predefined or how does it work.
I need to learn more topics on Rails can someone tell which is the best site to learn after beginner stage.
The requestuser_path route helper method does not exist.
Unless specified, route helper methods are autogenerated in Rails. To see a list of all these helpers and their corresponding controllers and actions, go to http://localhost:3000/rails/info/routes assuming you are running your development Rails server on port 3000.
In your case, the method you are looking for is request_path, not requestuser_path
To learn more about routes in Rails, the official documentation is a good resource. https://guides.rubyonrails.org/routing.html
Try not to use ruby keyword as routes or any controller's or model's name. Ruby will throw error. Try to rename the routes "match '/request', to: 'users#requestuser'"
It's always a good practice to run rails routes or rake routes to see how rails generates your routes, in your case pleas use request_path
It's not recommended to use match and even considered invalid in newer rails version:
If you want to expose your action to both GET and POST, add via: [:get, :post] option.
If you want to expose your action to GET, use get in the router:
Instead of: match "controller#action"
Do: get "controller#action"

Rails - Deploying to Heroku with duplicate routes

I'm deploying my Rails app that uses the clearance gem to Heroku. Everything works fine in development but I'm running into trouble with the gem generated routes I get.
When attempting to deploy to Heroku, I get the error...
ArgumentError: Invalid route name, already in use: 'sign_in'
You may have defined two routes with the same name using the `:as` option, or you may be overriding a route already defined by a resource with the same naming. For the latter, you can restrict the routes created with `resources` as explained here:
remote: http://guides.rubyonrails.org/routing.html#restricting-the-routes-created
I'm not seeing where to restrict the duplicates or where they would be generated with any of my resources:
Please see routes.rb file below
Routes.rb
Rails.application.routes.draw do
resources :passwords, controller: "clearance/passwords", only: [:create, :new]
resource :session, controller: "clearance/sessions", only: [:create]
resources :users, controller: "clearance/users", only: [:create] do
resource :password,
controller: "clearance/passwords",
only: [:create, :edit, :update]
end
get "/sign_in" => "clearance/sessions#new", as: "sign_in"
delete "/sign_out" => "clearance/sessions#destroy", as: "sign_out"
get "/sign_up" => "clearance/users#new", as: "sign_up"
get 'newSignUp', to: 'signups#new'
post 'newSignUp', to: 'signups#create'
get 'newTrip', to: 'trips#new'
post 'newTrip', to: 'trips#create'
get 'trips/:id/send_itinerary' => 'trips#send_itinerary', as: :trips_send_itinerary
root 'static_pages#home'
get 'static_pages/home'
get 'static_pages/help'
get 'static_pages/about'
get 'static_pages/contact'
resources :signups
resources :tripitems
resources :trips
end
This issue has to do with the clearance gem.
I am not totally familiar with the gem, so as per usual, I checked out the github and found the following:
# config/routes.rb
if Clearance.configuration.routes_enabled?
Rails.application.routes.draw do
resources :passwords,
controller: 'clearance/passwords',
only: [:create, :new]
resource :session,
controller: 'clearance/sessions',
only: [:create]
resources :users,
controller: 'clearance/users',
only: Clearance.configuration.user_actions do
resource :password,
controller: 'clearance/passwords',
only: [:create, :edit, :update]
end
get '/sign_in' => 'clearance/sessions#new', as: 'sign_in'
delete '/sign_out' => 'clearance/sessions#destroy', as: 'sign_out'
if Clearance.configuration.allow_sign_up?
get '/sign_up' => 'clearance/users#new', as: 'sign_up'
end
end
end
This is basically creating the same routes for you, only if the config routes_enabled? is true.
You need to configure clearance as follows to handle the routes yourself:
config.routes = false
After looking at the gems GitHub, it looks like I raked the routes earlier and even though config.routes was set to false in the initializer, there was a conflict generate in the generated resources in production.
I wound up deleting the raked routes and making config.routes=true.

Abstracting rails route

I want to replace the normal /users/:id route that is created by the resources command, with a more abstract /profile route. It won't be possible to view other users profiles in my app, and therefor the current route is unnecessary specific.
I have tried to overwrite the route created by 'resources :users' with:
get '/profile', to: 'users#show'
and other variances and combinations, but can't seem to get it right. Either the controller can't find the user because of a missing id or it simply can't find the route.
Thanks for the help!
You can use this code in routes.rb file:
resources :users, :except => :show
collection do
get 'profile', :action => 'show'
end
end
It will generate url "/users/profile".
But, if u want to use only '/profile', then don't create route as collection inside users resources block.
resources :users, :except => :show
get 'profile' => "users#show", :as => :user_profile
It will redirect '/profile' to show action in users controller.
I suggest simply adding a users/me route pointing to the show action of your UsersController like so:
resources :users, only: [] do
collection do
get 'me', action: :show
end
end
You can also use the match keyword in routes.rb file.
match 'users/:id' => 'users#show', as: :user_profile, via: :get

How to write match in route.rb

In my AdminController, I have methods named as edit, update and update_admin. And in route.rb
resources :session, :only => [update]
match '/:controller(/:action(/:id))'
end
When I navigate the url '/users/edit/1' matches. From this page i want to call the action method in update_admin in AdminController. How to do this?
My edit.erb has
<%= render :partial => '/submit', :locals =
> {:button_html => f.submit('Update'), :validate_present => true}
%>
at first, to check your routes go to console and do
rake routes | grep session
there you will get list all routes of your rails application (matched to the grep)
at second i dont get your routes.rb
would you do
resources :session, :only => [update] do
match '/:controller(/:action(/:id))'
end
or
resources :session, :only => [update]
match '/:controller(/:action(/:id))'
end
these are 2 different things. i think you want the last one. but here we go, there is another problem
resources :session, :only=>[update]
this throws an error.(undefined local variable or method `update' for #)
if you want to specify actions, you need to do it as a key
resources :session, :only=>[:update]
but you also want the edit message, (edit is the form, update the action to save the changes) so you have to do
resources :users, :only=>[:edit, :update]
now check your rake routes and see voila!
edit_session GET /session/:id/edit(.:format) {:action=>"edit", :controller=>"session"}
session PUT /session/:id(.:format) {:action=>"update", :controller=>"session"}
//edit
if you want to do this in your admin_controller you should have a namespace
#i take example for a user
namespace :admin do
resources :user :only => [:edit, :update]
end
if you want now to link to it from a view the route is named
edit_admin_user_path
and in a form you need to bring the namespace also in the form_for like:
=form_for [:admin, #user] do |f|

In Rails Routes redirect controller action to root?

I have a root path in my routes file:
root 'games#index'
The problem is that if anyone goes to: http://domain.com/games it doesn't show the root, thus we're creating two urls for the same page.
Is there a way to change any hit to http://domain.com/games to http://domain.com?
I'd rather not fiddle around with a before_filter in the application controller if there's a nice way to do it in the routes folder.
Thanks!
The easiest way is to just set up a redirect.
map.redirect('/games','/')
Although, your problem is really that the /games route shouldn't be there in in the first place.
Remove the catchall route at the bottom of your routes.rb file, and this won't even be a problem.
I had the same issue with sessions. I wanted to expose /sessions for login and logout, but since an invalid password leaves you at /sessions, I wanted a graceful way to deal with a user re-submitting that URL as a GET (e.g. by typing Ctrl-L, ). This works for me on Rails 3:
resources :sessions, :only => [:new, :create, :destroy]
match '/sessions' => redirect('/login')
match '/login', :to => 'sessions#new'
I think your code would look something like this:
resources :games, :only => [:new, :edit, :create, :destroy]
match '/games' => redirect('/')
routes.rb:
root 'games#index'
In controller:
def index
redirect_to root_path if request.env['PATH_INFO'] === '/games'
#games = Game.all
end
As of the current version of Rails (3.2.9), this is how I achieved the same result:
MyApp::Application.routes.draw do
# ...
# declare the redirect first so it isn't caught by the default
# resource routing
match '/games' => redirect('/')
# ...
resources :games
# ...
root :to => 'games#index'
end

Resources