I wish to map new_user path of the user resource to 'ROOT_DOMAIN/new' URL. My routes.rb looks something like this:
#new_user GET /users/new(.:format) users#new
# User Resource
match 'new', :to => 'users#new', via: [:get, :post]
resources :users do
collection do
match 'new', :to => 'users#new', via: [:get, :post]
end
end
So while I'm able to hit the /new URL to the desired action with
match 'new', :to => 'users#new', via: [:get, :post]
but the new_user path still leads to '/users/new'. How to remove the controller_name from the new_user method?
Your new_user_path takes you to user#new because that's how rails build resourceful routes. Have a look at rails guides to learn more. You need to pass the as: option to your routes in order to give them proper helper methods like:
post '/home' => "home#index", as: :home
This will give you two helpers home_path and home_url
Now you have
resources :users do
collection do
match 'new', :to => 'users#new', via: [:get, :post]
end
end
If you do rake routes in your terminal you'll see that new_user helpers are assigned to user#new. You need to give it a different path helper and then assign your new_user helpers to your custom route
resources :users do
collection do
match 'new', :to => 'users#new', via: [:get, :post], as: :old_new_user
end
end
and then you can use your new_user helper for your custom route
match 'new', :to => 'users#new', via: [:get, :post], as: :new_user
You can check your path helper by doing rake routes in terminal
Related
I'm trying to change the URL name.
This is my routes.rb:
namespace :user_management do
resources :user do
collection do
get 'main'
end
end
end
match ':controller(/:action(/:id(.:format)))', :via => [:get, :post]
Rake routes:
Prefix Verb URI Pattern Controller#Action
root GET / user_management/login#login
user_main_user_management_user_index GET /user_management/user/main(.:format) user_management/user#main
user_management_user_index GET /user_management/user(.:format) user_management/user#index
POST /user_management/user(.:format) user_management/user#create
new_user_management_user GET /user_management/user/new(.:format) user_management/user#new
edit_user_management_user GET /user_management/user/:id/edit(.:format) user_management/user#edit
user_management_user GET /user_management/user/:id(.:format) user_management/user#show
PATCH /user_management/user/:id(.:format) user_management/user#update
PUT /user_management/user/:id(.:format) user_management/user#update
DELETE /user_management/user/:id(.:format) user_management/user#destroy
GET|POST /:controller(/:action(/:id(.:format))) :controller#:action
My URL is:
localhost/user_management/user/main
And I want:
localhost/user_main
I tried this but it is not working:
namespace :user_management do
resources :user do
collection do
get 'main', as: :user_main
end
end
end
I tried this but is not working either:
namespace :user_management do
resources :user do
collection do
get '/user_main', as: "user_management/user#main
end
end
end
try
match "user_admin", :to => "user_management/user#main"
you can do like in example:
get 'exit', to: 'sessions#destroy', as: :logout # url => /logout
FROM RAILS ROUTING
I want to replace root to welcome controller,
But if I use the url http://localhost:3000/welcome/portfolio The action 'welcome' could not be found for WelcomeController
How to not affect original controller with the routes rule match '/:action(/:id)', :controller => "welcome",via: [:get, :post]
rake up routes
Prefix Verb URI Pattern Controller#Action
root GET / welcome#index
GET|POST /:action(/:id)(.:format) welcome#:action
portfolio_welcome_index GET /welcome/portfolio(.:format) welcome#portfolio
welcome_index GET /welcome(.:format) welcome#index
POST /welcome(.:format) welcome#create
new_welcome GET /welcome/new(.:format) welcome#new
edit_welcome GET /welcome/:id/edit(.:format) welcome#edit
welcome GET /welcome/:id(.:format) welcome#show
PATCH /welcome/:id(.:format) welcome#update
PUT /welcome/:id(.:format) welcome#update
DELETE /welcome/:id(.:format) welcome#destroy
route.rb
root :to => "welcome#index"
match '/:action(/:id)', :controller => "welcome",via: [:get, :post]
resources :welcome do
collection do
get 'portfolio'
end
end
it happens because /:action(/:id) handel each path with format /something/some_id and even /something so you could put it to the end in routes file:
resources :welcome do
collection do
get 'portfolio'
end
end
match '/:action(/:id)', :controller => "welcome",via: [:get, :post]
root :to => "welcome#index"
in this case request to /welcome/portfolio will be handled with resources definition before going to your /:action(/:id) definition.
i would like to perform an action on some of my routes, the problem is they are not in a 'resources' block because I need named methods for each. I want to be able to toggle the state of each an attribute in each item in an index type view. I wwas attempting to incorporate this tutorial.
devise_for :admins # The priority is based upon order of creation: first created -> highest priority.
root 'home#index'
resources :entries, :only => [:index, :new, :create]
namespace :admin do
namespace :entries do
match :pending, :via => [:get, :post], :collection => { :toggle_approve => :put}
match :rejected, :via => [:get, :post], :collection => { :toggle_approve => :put}
match :approved, :via => [:get, :post], :collection => { :toggle_approve => :put}
end
end
entries controller
class Admin::EntriesController < ApplicationController
expose(:entries){#entries}
def index
end
def show
end
def approved
#entries = Photo.with_approved_state
end
def pending
#entries = Photo.with_pending_state
end
def rejected
#entries = Photo.with_rejected_state
end
def toggle_approve
#a = Photo.find(params[:id])
#a.toggle!(:workflow_state)
render :nothing => true
end
rake routes
Prefix Verb URI Pattern Controller#Action
new_admin_session GET /admins/sign_in(.:format) devise/sessions#new
admin_session POST /admins/sign_in(.:format) devise/sessions#create
destroy_admin_session DELETE /admins/sign_out(.:format) devise/sessions#destroy
admin_password POST /admins/password(.:format) devise/passwords#create
new_admin_password GET /admins/password/new(.:format) devise/passwords#new
edit_admin_password GET /admins/password/edit(.:format) devise/passwords#edit
PATCH /admins/password(.:format) devise/passwords#update
PUT /admins/password(.:format) devise/passwords#update
cancel_admin_registration GET /admins/cancel(.:format) devise/registrations#cancel
admin_registration POST /admins(.:format) devise/registrations#create
new_admin_registration GET /admins/sign_up(.:format) devise/registrations#new
edit_admin_registration GET /admins/edit(.:format) devise/registrations#edit
PATCH /admins(.:format) devise/registrations#update
PUT /admins(.:format) devise/registrations#update
DELETE /admins(.:format) devise/registrations#destroy
root GET / home#index
entries GET /entries(.:format) entries#index
POST /entries(.:format) entries#create
new_entry GET /entries/new(.:format) entries#new
admin_entries_pending GET|POST /admin/entries/pending(.:format) admin/entries#pending {:collection=>{:toggle_approve_article=>:put}}
admin_entries_rejected GET|POST /admin/entries/rejected(.:format) admin/entries#rejected {:collection=>{:toggle_approve_article=>:put}}
admin_entries_approved GET|POST /admin/entries/approved(.:format) admin/entries#approved {:collection=>{:toggle_approve_article=>:put}}
I don't know where the collection option is from (I literally can't find reference to it anywhere)
Implementing non-resourceful routes is actually relatively simple:
#config/routes.rb
resources :entries, only: [:index, :new, :create] do
collection do
match :pending, via: [:get, :post] #-> domain.com/entries/pending
match :rejected, via: [:get, :post] #-> domain.com/entries/rejected
match :approved, via: [:get, :post] #-> domain.com/entries/approved
end
end
I don't understand the collection option - I don't think that belongs in your routes. Although having thought about it, I guess you're trying to make it so that if you receive a request to domain.com/entries/toggle_approve_article/pending you'll want to handle the reqeust?
If that's the case, why not just do this:
#config/routes.rb
resources :entries, only: [:index, :new, :create] do
put :toggle_approve #-> domain.com/entries/15/toggle_approve
collection do
match :pending, via: [:get, :post] #-> domain.com/entries/pending
match :rejected, via: [:get, :post] #-> domain.com/entries/rejected
match :approved, via: [:get, :post] #-> domain.com/entries/approved
end
end
i had to understand the difference between member and collections. collections are routes additional to a resource (eg, the restful actions). members are extra routes which can perform actions on their the block.
This...
resources :entries, :only => [:index, :new, :create]
namespace :admin do
resources :entries do
get :pending, on: :collection
get :approved, on: :collection
get :rejected, on: :collection
member do
get :toggle_approve_field
get :toggle_reject_field
end
end
end
yielded this rake routes
entries GET /entries(.:format) entries#index
POST /entries(.:format) entries#create
new_entry GET /entries/new(.:format) entries#new
pending_admin_entries GET /admin/entries/pending(.:format) admin/entries#pending
approved_admin_entries GET /admin/entries/approved(.:format) admin/entries#approved
rejected_admin_entries GET /admin/entries/rejected(.:format) admin/entries#rejected
toggle_approve_field_admin_entry GET /admin/entries/:id/toggle_approve_field(.:format) admin/entries#toggle_approve_field
toggle_reject_field_admin_entry GET /admin/entries/:id/toggle_reject_field(.:format) admin/entries#toggle_reject_field
admin_entries GET /admin/entries(.:format) admin/entries#index
POST /admin/entries(.:format) admin/entries#create
new_admin_entry GET /admin/entries/new(.:format) admin/entries#new
edit_admin_entry GET /admin/entries/:id/edit(.:format) admin/entries#edit
admin_entry GET /admin/entries/:id(.:format) admin/entries#show
PATCH /admin/entries/:id(.:format) admin/entries#update
PUT /admin/entries/:id(.:format) admin/entries#update
DELETE /admin/entries/:id(.:format) admin/entries#destroy
It took a lot of faffing around and I not sure I'd be able to do it upon request without more headache but I certainly have a better idea of rails routing all together. Thanks for the help from #RichPeck
I am attempting to setup my routes.rb so that /sessions/ is not required in the url for logging in and out of the site. Below are my samples to show what I am trying to achieve. Whilst the "second attempt" does in fact do what I want, I'd like to know if there is a more efficient way of doing this. I am very new to rails and I am sure that the routes.rb has some option that can do what I am doing in three large lines.
First attempt
routes.rb
namespace :account do
resources :users
resources :sessions
end
$ rake routes
Prefix Verb URI Pattern Controller#Action
account_users GET /account/users(.:format) account/users#index
...
account_sessions GET /account/sessions(.:format) account/sessions#index
POST /account/sessions(.:format) account/sessions#create
new_account_session GET /account/sessions/new(.:format) account/sessions#new
edit_account_session GET /account/sessions/:id/edit(.:format) account/sessions#edit
account_session GET /account/sessions/:id(.:format) account/sessions#show
PATCH /account/sessions/:id(.:format) account/sessions#update
PUT /account/sessions/:id(.:format) account/sessions#update
DELETE /account/sessions/:id(.:format) account/sessions#destroy
Second attempt
routes.rb
namespace :account do
resources :users
match '/login', :controller => 'sessions', :action => 'new', :via => [:get]
match '/login', :controller => 'sessions', :action => 'create', :via => [:post]
match '/logout', :controller => 'sessions', :action => 'destroy', :via => [:delete]
end
$ rake routes
Prefix Verb URI Pattern Controller#Action
account_users GET /account/users(.:format) account/users#index
...
account_login GET /account/login(.:format) account/sessions#new
POST /account/login(.:format) account/sessions#create
account_logout DELETE /account/logout(.:format) account/sessions#destroy
Can this be done without having to manually specific the match locations? All I want to do is remove /sessions/ as a requirement.
namespace :account do
resources :users #-> account/users
resources :sessions, path: "", path_names: { new: "login", create: "login", destroy: "logout" } #-> accounts/login, accounts/logout
end
I hope you realise you have /login twice in your second example. This simplifies it a bit but you will always have to match each route you want to specify outside any defaults.
namespace :account do
match '/login', to: 'sessions#new', via: [:get]
match '/logout', to: 'sessions#destroy', via: [:delete]
end
In rails3 we should use with_options in following way:
scope '/account' do
match '/login' => "sessions#new", :as => :login
post '/:login' => 'sessions#create', :as => :signup_create
delete '/:logout' => 'sessions#destroy', :as => :logout
end
I have been trying to implement a vanity url for user profiles, based on the example here: Rails 3: Permalink public profile. I have replaced the 'id' with username:
def to_param
username
end
However this has caused issues with my other routes. I have set them so that they match the default sets of routes exactly, when running 'rake routes'.
get '/users/' => 'users#index', :as => :users
post '/users' => 'users#create'
get '/users/new' => 'users#new', :as => :new_user
get '/users/:id/edit' => 'users#edit', :as => :edit_user
patch '/users/:id' => 'users#update'
put '/users/:id' => 'users#update'
delete '/users/:id' => 'users#destroy'
# for vanity url
get '/:id' => 'users#show', :as => :user
With this setup, trying to access delete and update routes give me 'no route matches' error. What is the proper way to specify these, and / or should I be doing this a different way? Any help is appreciated.
I think it's interresting and more readable to keep the resources syntax in the routes.rb, except for the show, which you can rewrite to customize user_path :
resources :users, :except => [:show]
# 2 possibilities for the show url
get '/users/:id' => 'users#show' # can be removed if you don't want to keep /users/:id url
get '/:id' => 'users#show', :as => :user
But change the controller to find user by username instead of id, for example
def show
#post = Post.find_by_username(params[:id]) # instead of Post.find(params[:id])
# ...
end