I have 3 levels of nesting.
routes.rb looks like this
resources :clients do
resources :departments do
resources :tasks
end
end
I would like to create a custom path that looks like this
/clients/:client_id/departments/:department_id/tasks/data
I have tried adding the following
resources :clients do
resources :departments do
resources :tasks
member do
get "data"
end
end
end
This creates the route
/clients/:client_id/departments/:department_id/tasks/:task_id/data
How would I remove the :task_id part the path?
A member route acts on a member, that's why it requires an id. A collection acts on a collection and so doesn't require an id.
resources :clients do
resources :departments do
resources :tasks do
collection do
get "data"
end
end
end
end
You should use
resources :clients do
resources :departments do
resources :tasks
get "data", :on => :collection
end
end
Related
Some routes are for CRUD operations, such as client, phone_numbers and products. I have 'unique-index' attributes for many of the models. For example, in Client, I could have "email" or "username", whereas in Products I could have "serialnumber", and in PhoneNumber the actual "number" could be unique-index.
So, I have methods in my ApplicationController that receives a JSON in a POST request, with the attribute name and attribute value. The server checks if the value exists and informs the user if the input is valid or if value exists.
So, for these models, I have to declare a route that points to the "unique" method, such as below
routes.rb
resources :clients
resources :phone_numbers
resources :products
post 'clients/unique' => 'clients#unique'
post 'phone_numbers/unique' => 'phone_numbers#unique'
post 'products/unique' => 'products#unique'
My question is: Can I "group" these routes, without prefix (unlike namespace and scope) to just add post 'unique' to them? a pseudo-code would be like this
pseudo-code
group alias: 'modelsWithUniqueAttrs'
resources :clients
resources :phone_numbers
resources :products
add_route 'unique'
end
Try this
resources :clients, :phone_numbers, :products do
collection do
post :unique
end
end
Or
unique_routing = Proc.new do
collection do
post :unique
end
end
resources :clients, &unique_routing
resources :phone_numbers, &unique_routing
resources :products, &unique_routing
Or
unique_routing = Proc.new do
collection do
post :unique
end
end
resources :clients, :phone_numbers, :products, &unique_routing
You can define your routes like this:
resources :clients do
member do
post :unique => 'clients#unique'
end
end
resources :phone_numbers do
member do
post :unique => 'phone_numbers#unique'
end
end
resources :products do
member do
post :unique => 'products#unique'
end
end
These will give you routes like:
unique_client POST /clients/:id/unique(.:format) clients#unique
unique_phone_numbers POST /phone_numbers/:id/unique(.:format) phone_numbers#unique
unique_products POST /products/:id/unique(.:format) products#unique
Update
You can define routes using collection block like this:
resources :clients, only: [:uniq] do
collection do
post :uniq
end
end
which you give you routes like:
uniq_clients POST /clients/uniq(.:format) clients#uniq
But, this is still not what you want exactly. Because, you have to have the similar collection blocks for products and phone_numbers as well.
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 have nested routes which goes something like this:
resources :venues do
#Halls
get "hall/:id/exhibition" => "halls#exhibition", as: :exhibition
get "hall/:id/visit" => "halls#visit", as: :hall_visit
get "venue_structure", :to => "venues#venue_structure"
resources :asset_types, :booths_tags, :tags, :uploaded_files, :events, :chats
resources :halls do
resources :webcasts
resources :booths do
resources :chats
end
end
end
Problem with this approach is that I have to put in three paramters in url helpers for nested ones like below:
venue_hall_booth_path(#booth.hall.venue, #booth.hall, #booth)
Is there a better approach to doing this other than me having to put in three different resources as parameters each time when I use this helper?
You can use shallow routes:
resources :halls, shallow: true do
resources :webcasts
resources :booths do
resources :chats
end
end
This allows you access member urls without having to use the parent. Unless it's a new or create actions.
Or you can define them separately.
resources :booths do
resources :chats
end
resources :halls do
resources :webcasts
resources :booths
end
I have several levels of nested routing.
resources :departments do
resources :tasks do
collection do
get "report" => "tasks#report"
end
end
This a piece of it.
What I am attempting to do is create a custom route for a report.html.erb file. However, this route creates the path /department/:id/tasks/report
I would like to create the path /department/:id/tasks/:id/report
Is this possible? I considered creating a new controller and model for report but this seems to be inefficient.
try with:
resources :departments do
resources :tasks do
member do
get "report" => "tasks#report"
end
end
end
or just:
resources :departments do
resources :tasks do
get "report" => "tasks#report", :on => :member
end
end
I have 2 resources events and patients
resources :events do
collection do
get :upcoming
get :missed
end
end
resources :patients do
resources :events # does not have upcoming or missed
end
Is there a way to have the events nested resource within the patients definition share the custom collection members from the primary events resource without having to define them again?
You can define a method in your routes file and can call it each time, as such keep DRY.
def events_actions
collection do
get :upcoming
get :missed
end
end
resources :events do
events_actions
end
resources :patients do
resources :events do
events_actions
end
end
Or take things even further:
def resources_events
resources :events do
collection do
get :upcoming
get :missed
end
end
end
resources_events
resources :patients do
resources_events
end