Here is code from my routes.rb
Rails.application.routes.draw do
resources :session, only: [:create, :destroy, :new]
end
and the relevant output of rake routes is
session_index POST /session(.:format) session#create
new_session GET /session/new(.:format) session#new
session DELETE /session/:id(.:format) session#destroy
My question is, why does session#create route to session_index, and not simply session?
It should be:
resources :sessions, only: [:create, :destroy, :new]
As per Rails convention, if you use singular resource, then simply use resourceand for plural resource, you should use resources.
Resource Routing
Related
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.
I have this route in my routes.rb
resource: session
It generates the following routes
session_path POST /session(.:format) sessions#create
new_session_path GET /session/new(.:format) sessions#new
edit_session_path GET /session/edit(.:format) sessions#edit
I do not require edit_session_path (at least I don't know yet whether I require it or not) and I have a custom route for signin, so I don't want new_session_path.
Is there a way to tell Rails to not generate these two paths?
resources :sessions, :except => [:new, :edit]
Alternatively, if you know which actions you want you can provide it directly via only, instead of excepting them:
resources :sessions, only: [:create]
If you need more than 1 resource to configure
with_options(except: [:new, :edit]) do |opt|
opt.resource :session
opt.resource :another_resource
opt.resources :people
end
like in this post
or like this - similar to the upper answer.
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)
I understand resource and path routes in rails 3 but I do not know is there any way to have both routes ? I try this routes but it not work for me, this is the routes:
resources :roles, only: [:index, :create, :show, :update]
get '/roles/:id' => 'roles#available_users'
How can we routes to use both routes ?
thankyou very much
Routes
What you're asking for cannot be done, as you'll be using the same "route" for different controller actions:
#config/routes.rb
resources :roles, only: [:index, :create, :show, :update] #-> domain.com/roles/:id - roles#show
If you then create another route for domain.com/roles/:id, Rails will just take the first which it finds in the routes file
--
The way to fix your issue is likely to be down to the following:
#config/routes.rb
resources :roles, except: [:edit, :destroy] do
get :available_users # -> domain.com/roles/:id/available_users
end
This will take you to the roles#available_users action, providing you with the ability to load the view you wish (to display the users for a particular role)
For a more defined explanation, I'd recommend checking out the nested_resources part of the Rails routing system
If I understand you correctly you want something like this:
resources :roles, only: [:index, :create, :update] do
get '/roles/:id' => 'roles#available_users'
end
Correct?
Just add an "do" behind the closing ] and an end after the custom routes.
Edit: Apparently I got wrong. ;) What you could do is:
resources :roles, only: [:index, :create, :show, :update] do
get '/roles/:id/available' => 'roles#available_users'
end
I have routes like this below. Is it possible if I have routes like this ?
#config/routes
resources :subscribers, only: [:index, :show]
namespace :admin do
resources :subscribers, only: [:new, :edit, :update, :create, :destroy]
end
I have tried to run rake routes and the result is
admin_subscribers POST /admin/subscribers(.:format) admin/subscribers#create
new_admin_subscriber GET /admin/subscribers/new(.:format) admin/subscribers#new
edit_admin_subscriber GET /admin/subscribers/:id/edit(.:format) admin/subscribers#edit
admin_subscriber PUT /admin/subscribers/:id(.:format) admin/subscribers#update
DELETE /admin/subscribers/:id(.:format) admin/subscribers#destroy
subscribers GET /subscribers(.:format) subscribers#index
subscriber GET /subscribers/:id(.:format) subscribers#show
the result was appropriate with my expectation, but when i run my RSpec i got errors
Routing Error
uninitialized constant Admin::SubscribersController
Try running rake routes for more information on available routes.
I added this code below in my Rspec Helper too
#spec/spec_helper.rb
Spork.each_run do
###
if /spork/i =~ $0 || RSpec.configuration.drb?
ActiveSupport::Dependencies.clear
end
###
end
But, if I fire my browser to htt**://l*alhost:3000/admin/subscribers/new, everything is fine.
Am I missing something ?
As stated in the docs
If you want to route /admin/subscribers to SubscribersController (without the Admin:: module prefix), you could use scope instead of namespace
#config/routes
resources :subscribers, only: [:index, :show]
scope "/admin" do
resources :subscribers, only: [:new, :edit, :update, :create, :destroy]
end
I don't think there's much need for you to namespace this under admin. You could just fill in all the actions on SubscribersController and set the permissions on create, update etc. appropriately.