In Ruby on Rails, is there a way to add another RESTful action to the base URL of a plural resource? I'm looking for something like this:
resources :groups do
resources :users do
put on: :base, to: 'users#update_all'
end
end
Which would generate the route: [PUT] groups/:group_id/users => users#update_all
I've already tried doing this:
resources :groups do
resources :users
put 'users', on: :member, to: 'users#update_all'
end
But that doesn't preserve the value of params[:group_id] in the controller.
resources :users do
collection do
put '' => 'users#update_all' ## PUT /users
end
end
UPDATE
It would be recommended to do this though:
resources :users do
collection do
put 'update_all' ## PUT /users/update_all
end
end
Both route to the update_all action of the users controller.
RESOURCES
http://guides.rubyonrails.org/routing.html#adding-more-restful-actions
Related
I have a rails nested resource in my routing.
i.e
resources :users do
resources :accounts
end
resources :accounts
The listing operations of course will be:
GET /users
GET /users/:user_id/accounts
I want to get rid of the /users route but retain the /users/:id/accounts route.
Any idea how I can go about this? Thanks
Using except: [:index] not will restrict both routes. Thats a nonsenical claim that can easily be refuted by just running rails routes. None of the options for resources "trickle down" to nested calls.
resources :users, only: [] do
resources :accounts, only: :index
end
only: [] skips generation of all the "user" routes.
This will generate the routes:
Prefix Verb URI Pattern Controller#Action
user_accounts GET /users/:user_id/accounts(.:format) accounts#index
# ...
Note that the param key is :user_id and not :id. If you REALLY want to break the conventions you would need to do:
# don't do this - its stupid
scope '/users/:id', as: :user do
resources :accounts, only: :index
end
let set only: [] then rails routes will generate /users/:id/accounts as you want
resources :users, only: [] do
resources :accounts # , only: [:index] if you just only keep users/:id/accounts
end
# if you only want to get rid of GET /users
resources :users, except: [:index]
# if you mean you want to get rid all of /users routes (not just only GET /users) then comment above line
This is what scope is for
scope :users do
resources :accounts
end
Rails guides on routing
Or you can use these same two ways, use namespace with scope:
namespace :users do
scope ':user_id' do
resources :accounts
end
end
Use just only scope:
scope ':users/:user_id' do
resources :accounts
end
routes.rb
Rails.application.routes.draw do
root to: 'visitors#index'
resources :states do
resources :cities do
get 'listings'
end
end
end
I am looking to have my GET URL set up like:
../state.id/city.id/listings.id
I am using friendly_id so the urls will read like:
../OR/Portland/2011-ford-truck
Listing is it's own model (resource) too in this case. You will also need a resources for listing. If it only has a show action, you can limit it like this:
resources :states do
resources :cities do
resources :listings, only: [:show]
end
end
I'm wanting to make a product resource :locationable (meaning, can be filtered by its location).
# routes.rb
concern :locationable do
member do
get 'location/:location_id'
end
end
resources :products, concerns: :locationable, action: :index
The routes above create the following route:
/products/location/:location_id
However, I'm wanting it to put the location first in the route. For example:
/location/:location_id/products
I'm wanting to use concerns for this--not nested resources.
What about changing it to
# routes.rb
concern :locationable do
resources :products, only: :index
member do
get 'location/:location_id'
end
end
Check out routing concerns from here https://gist.github.com/dideler/10020345.
Let's assume I have models: Article, Post, and Comment. For these models I need to map CommentsController#show in articles and posts. Something like this:
resources :articles do
resources :comments, :only => [:show]
end
resources :posts do
resources :comments, :only => [:show]
end
And this works perfectly, i.e. it'll generate routes something like this:
/articles/:article_id/comments/:id
/posts/:post_id/comments/:id
Both pointing to the same controller's single method: CommentsController#show
What I need is to include more/multiple parameters for posts while retaining the same URL routes to CommentsController:
/articles/:article_id/comments/:id
/posts/:post_id/:post_title/:post_year/comments/:id
I tried match but first occurrence at resources :articles do... overrides it.
resources :articles do
resources :comments, :only => [:show]
end
match '/posts/:post_id/:post_title/:post_year/comments/:id', :to => 'comments#show', :as => :show_post_comments
It throws an error:
No route matches {:controller=>"comments", :action=>"show",
:post_id=>10, :post_title=>"some title", :post_year=>"1995", :id=>"1"}
So, is it possible to create such a route with multiple parameters to single controller's method in two resources using get or something?
I changed the routing of posts#index to match blog and I now get /blog in the URL which I was trying to accomplish.
I've tried several different things to get my actual blog post which the route currently looks something like /posts/this-is-a-test to also use blog rather than posts in the URL.
Below is my current route file. I am using the friendly_id gem, if that makes any difference in answering this question.
resources :posts do
resources :comments
end
resources :contacts, only: [:new, :create]
root "pages#home"
get "/home", to: "pages#home", as: "home"
get "about" => 'pages#about'
get "pricing" => 'pages#pricing'
get "contact_us" => 'pages#contact_us'
match 'blog', to: 'posts#index', via: :all
end
path option along with resource must help.
resources :posts, :path => 'blogs' do
resources :comments
end
This will change all /posts and /post to /blogs/ and /blog.
If you want to change your route's helper methods such as posts_path to blogs_path and new_post_path to new_blog_path etc, you can change it with as tag.
resources :posts, :path => 'blogs', :as => 'blogs' do
resources :comments
end
Or yet better, you can specify the controller and route blogs directly as:
resources :blogs, controller: 'posts' do
resources :comments
end
This is the awesomeness of Rails! :)
match 'blog/:id' => 'posts#show'
should work. But if you want to match every method in posts controller to blog (and you don't want to use the posts path), I would just rename the controller to blog instead and add resource :blog in the routes.
This helped me, from official guides documentation, add this in your routes.rb file:
get '/patients/:id', to: 'patients#show', as: 'patient'