I am using this as an example:
https://github.com/toshimaru/Rails-4-Twitter-Clone
The route file looks like:
Rails.application.routes.draw do
root 'static_pages#home'
resources :users do
member do
get :following, :followers
end
end
resources :sessions, only: [:new, :create, :destroy]
resources :tweets, only: [:index, :create, :destroy]
resources :relationships, only: [:create, :destroy]
get 'signup' => 'users#new'
get 'signin' => 'sessions#new'
delete 'signout' => 'sessions#destroy'
get 'about' => 'static_pages#about'
match '*path' => 'application#routing_error', via: :all
end
It appears that in some controllers there are comments mentioning which route it uses, however it's not specified in the route file. For instance:
# GET /users
def index
#users = User.all
end
# GET /users/1
def show
#tweet = current_user.tweets.build if signed_in?
#feed_items = #user.tweets.paginate(page: params[:page])
end
(in users_controller.rb)
My question is, how does rails app know that there is an endpoint here? I would like to know whether I can actually collect all the routes in one file?
What I am intending to do is, I would like to replace current routes.rb file with all routes.
Its specified in route file
When, we write
resources :users
It creates CRUD routes for specified resource namely index, new, create, show, edit, update, destroy routes for resource, here in this case resource is user.
You can see all routes for user by
rake routes | grep 'users'
and to list all routes in application
rake routes
resources :users has automatically created all RESTful routes for you, although you can limit it to only certain routes (as your example does with sessions, tweets, and relationships).
You can see all the routes from the console... in the root of your project do rake routes
See here for an explanation...
http://guides.rubyonrails.org/routing.html#listing-existing-routes
You can access the output of rake routes in your application....
output = `rake routes`
(note the use of backticks in the above)
Related
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"
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.
In my app I have grants and I want the url to be root/grant_id instead of root/grants/grant_id. I have this in my routes
Rails.application.routes.draw do
...
root 'static_pages#welcome'
# get 'home' => 'static_pages#home'
get 'about' => 'static_pages#about'
get 'faq' => 'static_pages#faq'
get 'signup' => 'users#new'
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
get 'dashboard' => 'dashboard#index'
resources :users do
resources :projects
member do
get 'access_granted'
put 'access_granted'
get 'remove_access'
put 'remove_access'
end
end
resources :profiles
resources :account_activations, only: [:edit]
resources :password_resets, only: [:new, :create, :edit, :update]
resource :request_access, only: [:show, :new, :create]
resources :grants, :path => '' do
resources :app_types do
resources :submissions
end
end
get 'grants' => 'grants#index'
resources :matches
end
When I put resources :matches below the resources :grants, :path => '' do line I get the error "Couldn't find Grant" and I see that request parameters are
{"controller"=>"grants", "action"=>"show", "id"=>"matches"}. When I put resources :matches above the the grant line everything works fine. Its almost like something in the grant route isn't closing and is forcing any lines below it to look for the grant controller. A simple solution is just keeping everything above that line but I'm trying to understand why this is happening.
I also noticed that even though I define the grant#index as grants, when I rake routes I see:
grants GET / grants#index
GET /grants(.:format) grants#index
So two questions
1. Is :path => '' the correct way to remove the grants/ part of the url.
2. Why is everything below the grants route getting sent to the grants controller?
From the documentation :
Rails routes are matched in the order they are specified, so if you have a resources :photos above a get 'photos/poll' the show action's route for the resources line will be matched before the get line. To fix this, move the get line above the resources line so that it is matched first.
So, the problem you're having is that matching grants to "" means your grants INDEX route is /, and your grants SHOW route is /:grant_id, which will match any route. If you want to have this kind of route (which I would advise against), it has got to be at the bottom of the routes file.
You can read more about routing here: http://guides.rubyonrails.org/routing.html
I'm trying to define custom routes to my controller and I need to use some of the default routes too. Is there any simple solution?
So far I've something like this
resources :users do
member do
get 'users/:id', to: 'users#show'
delete 'users/:id', to: 'users#destroy'
end
collection do
post 'users', to: 'users#create'
post 'users/login', to: 'users#login'
end
end
resources :users, :only => [:show, :destroy, :create, :login]
I don't need nor want the index route but with this settings it's still trying to route GET users/ to user_controller index method.
I know that there is probably some simple and obvious answer but I'm not able to find it.
Thank's in advance.
You got your routes wrong. The resources :users generates seven default routes which include the index route as well. You need to tweak the code to below
resources :users, :only => [:show, :destroy, :create] do
collection do
post 'login', to: 'users#login'
end
end
Note:
If you noticed, I've removed the custom routes for show,create and delete as they are generated by default.
Your first line defines the route to the index action. Define a resource once only. Read the routing guide.
resources :users, :except => [:index] do
collection do
post 'users/login', to: 'users#login'
end
end
Run rake routes from the command line in your project root folder to see all your route definitions.
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