I am trying to add a few new pages to a rails resource that I am creating.
What I am doing in my routes file is as follows:
resources :users, :only => [:index, :show] do
collection do
get :show_subpage1
end
end
When I look at my routes, show_subpage1 shows up, but not in the format I want. What shows up in the routes is:
show_subpage1_users GET /users/show_subpage1(.:format)
When what I WANT the route to be is:
show_subpage1_users GET /users/:id/show_subpage1(.:format)
(with the ID).
How would I go about doing that in rails?
To get:
show_subpage1_users GET /users/:id/show_subpage1(.:format)
do not define :show_subpage1 as a collection route:
resources :users, :only => [:index, :show] do
get :show_subpage1
end
or you could define it as a member route as follows:
resources :users, :only => [:index, :show] do
member do
get :show_subpage1
end
end
Also, I'm unsure why you have :only => [:index, :show] defined if you are also going to have a member route :show_subpage1. I assume you do want to add add :show_subpage1 to the only array, i.e. resources :users, :only => [:index, :show, :show_subpage1] do.
Please take a read on "Adding More RESTful Actions"
there are two ways with resources member or collection
resources :users, :only => [ :index, :show ] do
# /users/:id/profile
get 'profile', :on => :member
# /users/profile
get 'profile', :on => :collection
end
hope this helps
Related
I've the following nested route:
resources :carts, only: [:show, :update, :create], param: :token do
resources :items, :controller => :cartitems, except: [:new, :edit], param: :product_id
end
This generates
GET /api/merchants/:merchant_id/carts/:cart_token/items(.:format) cartitems#index
POST /api/merchants/:merchant_id/carts/:cart_token/items(.:format) cartitems#create
GET /api/merchants/:merchant_id/carts/:cart_token/items/:product_id(.:format) cartitems#show
PATCH /api/merchants/:merchant_id/carts/:cart_token/items/:product_id(.:format) cartitems#update
PUT /api/merchants/:merchant_id/carts/:cart_token/items/:product_id(.:format) cartitems#update
DELETE /api/merchants/:merchant_id/carts/:cart_token/items/:product_id(.:format) cartitems#destroy
...
I want to remove the controller part in the resources :items parameters. That means: I want to rename the :cart_token parameter to :token. Just like:
GET /api/merchants/:merchant_id/carts/:token/items(.:format) cartitems#index
POST /api/merchants/:merchant_id/carts/:token/items(.:format) cartitems#create
GET /api/merchants/:merchant_id/carts/:token/items/:product_id(.:format) cartitems#show
PATCH /api/merchants/:merchant_id/carts/:token/items/:product_id(.:format) cartitems#update
PUT /api/merchants/:merchant_id/carts/:token/items/:product_id(.:format) cartitems#update
DELETE /api/merchants/:merchant_id/carts/:token/items/:product_id(.:format) cartitems#destroy
...
How can this be achieved?
Don't know if it's the best way to do that, but I got the routes you expected there by:
scope 'api/mechantes/:merchant_id/carts/:token' do
resources :items, :controller => :cartitems, except: [:new, :edit], param: :product_id
end
Hope this can helps. Good luck!
I have following relationship routes:
resources :courses, only: [:index, :show] do
resources :enrols, only: [:new, :create]
resources :lectures, only: [:show]
end
resources :code_casts, :path => 'casts', :as => 'casts', only: [:index, :show]
resources :blogs, :path => 'blog', :as => 'blog', only: [:index, :show] do
resources :blog_votes, only: [:create, :destroy]
end
I want polymorphic comments in courses, lectures, code_casts and blog.
Problem is lecture has a parent of course so route will be course/course_id/lecture/id and blog path will blog/id where comments will have different show pages.
If I understand the problem correctly, there is nothing special about deeply nested resources. So you might need something like this
# routes.rb
concern :commentable do
resources :comments
end
resources :courses, only: [:index, :show] do
resources :enrols, only: [:new, :create]
resources :lectures, only: [:show], concerns: [:commentable]
end
resources :code_casts, :path => 'casts', :as => 'casts', only: [:index, :show]
resources :blogs, :path => 'blog', :as => 'blog', only: [:index, :show], concerns: [:commentable] do
resources :blog_votes, only: [:create, :destroy]
end
This will create nested comments resources for lectures and blogs.
Than you need to differentiate the path in a comments controller
# comments_controller
def create
Comment.create(commentable: commentable, other_params...) # assuming you have `commentable` polymorphic belongs_to
end
# a little more ugly than Ryan suggests
def commentable
if request.path.include?('blog') # be careful. any path with 'blog' in it will match
Blog.find(params[:id])
elsif params[:course_id] && request.path.include?('lecture')
Course.find(params[:course_id).leactures.find(params[:id]) # assuming Course has_many lectures
else
fail 'unnable to determine commentable type'
end
end
All 'magic' is in commentable method, where youare checking the path and determine which commentable object to pick. I use similar approach, but this exact code is written by memory without testing. Hopefully you've got the idea.
I have my user_controller and the action create. I do however want to set a custom route to the create action so when the user hits register the create action sets the url to user/thank-you. I have added the following match to my routes file but the url stays unchanged after hitting the register button. Here is part of my routes file until the line with thank-you.
get '/:locale' => 'pages#home'
root :to => 'pages#home'
scope "(:locale)", locale: /en|es/ do
get "javascripts/dynamic_cities"
get "javascripts/dynamic_cities_to_stadia"
get "javascripts/dynamic_stadia"
get "javascripts/dynamic_modality_to_max_players"
get "tournaments/edit_info"
get "tournaments/seasons"
get "league_rosters/cancel_new"
get "tournament_administrations/cancel_new"
resources :admin_tasks, :only => [:index]
resources :sports
resources :countries
resources :cities
resources :stadia
resources :users
resources :sessions, :only => [:new, :create, :destroy]
resources :teams
resources :tournaments
resources :leagues
resources :brackets, :only => [:new, :create, :edit, :update, :show]
resources :labs, :only => [:show, :edit]
resources :seasons, :only => [:edit, :show, :destroy]
resources :matches, :only => [:show, :edit, :update]
resources :player_participations
resources :highlights
resources :users do
resources :requests, :name_prefix => "user_"
end
# match 'league/:id/subscription' => 'league_rosters#new', :as => :subscription
match '/contact', :to => 'pages#contact'
match '/terms_and_conditions', :to => 'pages#terms_and_conditions'
match '/about_us', :to => 'pages#about_us'
match '/cookie_excluder', :to => 'pages#cookie_excluder'
match '/vacancies', :to => 'pages#vacancies'
match '/signup', :to => 'users#new'
match '/thank-you', :to => 'users#create'
Here is also the create method in the users_controller.rb
def create
# Note: This function is repeated in request controller in the invitations part. So any change should be added to request controller aswell
#user = User.new(email: params[:user][:email].downcase,
name: params[:user][:name].capitalize,
password: params[:user][:password],
password_confirmation: params[:user][:password_confirmation],
language: params[:user][:language])
#for user_menu
#title = t("user.new.title")
if #user.save
confirmation_code = "#{#user.id}#{random_string}"
if #user.update_attributes(confirmation_code: confirmation_code)
UserMailer.welcome_email(#user).deliver
vars = Hash.new
vars[:cc] = "#{confirmation_code}"
confirmation_url = url_maker(params[:request_protocol], params[:request_host_with_port], params[:request_locale], "#{email_confirmation_path}", vars)
UserMailer.confirm_email(#user, confirmation_url).deliver
sign_in #user
#user_tournaments = current_user.tournaments.all(:order => "name ASC")
#user_teams = current_user.teams.all(:order => "name ASC")
else
render 'new'
end
else
render 'new'
end
end
Is it possible for this to work the way I am approaching it or I will have to make a redirect and a thank-you page, which I can easily manage through my pages controller?
Move your thank-you route above the resources block as follows:
...
get "league_rosters/cancel_new"
get "tournament_administrations/cancel_new"
# Move route here
match '/thank-you', :to => 'users#create', via: [:post]
resources :admin_tasks, :only => [:index]
resources :sports
...
I'm also adding via: [:post] to the route since:
Routing both GET and POST requests to a single action has security implications. In general, you should avoid routing all verbs to an action unless you have a good reason to.
[http://guides.rubyonrails.org/routing.html]
I have this in my routes.rb
resources :users, :path => "/", :only => [:show] do
resources :collections, :controller => 'users/collections'
end
Why can I access to collections resources from:
http://localhost:3000/en/collections
if this resouce this inside users?
I want that collection resource only is enable inside:
http://localhost:3000/en/users/collections
This is my routes:
user_collections GET (/:locale)/:user_id/collections(.:format) users/collections#index
POST (/:locale)/:user_id/collections(.:format) users/collections#create
new_user_collection GET (/:locale)/:user_id/collections/new(.:format) users/collections#new
edit_user_collection GET (/:locale)/:user_id/collections/:id/edit(.:format) users/collections#edit
user_collection GET (/:locale)/:user_id/collections/:id(.:format) users/collections#show
PUT (/:locale)/:user_id/collections/:id(.:format) users/collections#update
DELETE (/:locale)/:user_id/collections/:id(.:format) users/collections#destroy
How can I do it?
Thank you
Try this:
resources :users, :only => [:show] do
resources :collections, :controller => 'users/collections'
end
I have a projects controller/model. Instead of listing projects on the #index page, I show a list of drop downs, which submits to projects#select, which finds the right Project (I've made sure there can only be 1 for each combination of options) and forwards the user to the #show page for that Project.
So for my routes I do this...
resources :projects, :only => [:index, :show] do
collection do
get 'select'
end
end
And thats fine, but the helper method for #select is 'select_projects', which is understandable but in my case I really want 'select_project'. And I really don't want to alias this in another file. No problem I can use :as...
resources :projects, :only => [:index, :show] do
collection do
get 'select', :as => 'select_project'
end
end
But now my helper is 'select_project_projects'. So I cheat a little (still better than aliasing in another file)...
resources :projects, :only => [:index, :show]
match '/projects/select', :to => 'projects#select', :as => 'select_project'
This looks like it might work, but it doesn't because /project/select actually matches the route for 'project#show'. Changing the order of the lines does the trick.
match '/projects/select', :to => 'projects#select', :as => 'select_project'
resources :projects, :only => [:index, :show]
But is there a more elegant way of handling this? I realize this is borderline OCD, but I'd like to be able to have complete control over the route name within the resources block.
use resource instead of resources
you probably don't want to make it a collection route but a member route:
resources :projects, :only => [:index, :show] do
member do
get 'select'
end
end
This way you'll have the select_project helper.
For those that want to rename the helper method side of things (as the title suggests):
resources :posts, as: "articles"