So far I have my routes like this: ( out of learning purposes I am curious to get it working with nested resources technique, but if you think this will get too complicated please feel free to suggest any other way of routing technique too)
resources :management, only: [:show] do
resources :report, only: [:show], controller: 'report' do
member do
# hmm what to write in here?!
end
end
end
my GOAL is to have a URL like this:
/managment/SOME_ID_WE_PASS_/report
/managment/1/report
But still can't figure out how exactly to write that route? Can you please take a look?
You don't need nested resources.
resources :crowd_management, only: [:show] do
get :exec_report, on: :member
end
That will produce:
/crowd_management/:id mapped to CrowdManagementController#show
/crowd_management/:id/exec_report mapped to CrowdManagementController#exec_report
The helper methods will be:
crowd_management_path
exec_report_crowd_management_path
You can run rake routes for a detailed list of all your routes.
Related
My routes.rb file looks like:
resources :contents, only: [:show]
get 'contents/by_hardware', to: 'contents#show_by_hardware'
With this setup I am not able to access the contents/by_hardware route.
But if I setup my routes.rb file in a different order, everthing works.
get 'contents/by_hardware', to: 'contents#show_by_hardware'
resources :contents, only: [:show]
Is the order in the routes.rb file important?
Yes, order matters very much.
It works like this: resources :contents, only: [:show] creates this route
content GET /contents/:id(.:format) contents#show
So when you request, for example, http://localhost:3000/contents/by_hardware, it is this route that matches this url. It invokes ContentsController#show action with params {'id' => "by_hardware"}. Your custom action is not considered, because matching route is already found.
Yes, order does matter. Instead of defining routes for the same controller at two different places, I would recommend you to define routes for the above scenario this way
resources :contents, only: [:show] do
get :show_by_hardware, on: :collection, path: :by_hardware
end
Hope that helps!
Yes it is important, the routes will be matched from top to bottom so you can move your route get 'contents/by_hardware', to: 'contents#show_by_hardware' above resource to fix your problem
yes. router will match first route from the top
In my application, a User can make a Post, and a User can make Correction (think of it as a comment) on another user's post. Each User can have many Posts, and each Post can have many Corrections.
On each show page for a Post, there is a form to create a new Correction. This uses the user_post_corrections path.
On the show page for each User, I would like to display each Correction they've submitted for any Post. This requires a user_corrections path.
In order to achieve this, I have the following in my routes.rb:
resources :users do
resources :posts do
resources :corrections
end
end
resources :users do
resources :corrections
end
This intuitively feels bad to me, as I've created two nested routes that are very similar to one another.
Is there a better way to do this? My code is working fine as it is but is there a best practice method for implementing this kind of model?
Routing concerns are an excellent but underused tool for DRYing out your routes:
concern :correctable do
resources :corrections
end
# just an example of multiple concerns
concern :commentable do
resources :comments
end
resources :users, concerns: :correctable
resources :posts, concerns: [:correctable, :commentable]
However you should take when creating nested routes so that you are not nesting needlessly.
Often you might want the collective actions [new, index, create] to be scoped by the parent:
GET|POST /posts/:post_id/corrections
GET /posts/:post_id/corrections/new
While you want the member actions to be unscoped since you can always access a record directly if it has a unique id.
GET /corrections/:id
GET /corrections/:id/edit
PATCH /corrections/:id
DELETE /corrections/:id
To do this you would declare the routes like so:
resources :corrections, only: [:show, :update, :edit]
concern :correctable do
resources :corrections, only: [:new, :index, :create]
end
resources :users, :posts, concerns: [:correctable]
The shallow: true option does something like this but does not work well when you declare the same resources several times as it adds unscoped routes for every call.
I'd like to use scoped routes for internationalizing. Here's my routes.rb
scope "(:locale)", locale: /en|pl/ do
resources :announcements, only: [:index], path: '/news'
resources :diplomas, only: [:index, :show], path: '/graduates'
end
Goal is to point urls like website.domain/pl/news to announcements controller and then check params[:locale] in ApplicationController in some before_action method.
But I have problems with generating urls. As I said before I want only good looking urls and my sense of aesthetics tells me that appname.domain/news/?locales=pl is not something I'm looking for. :(
So I have question:
Is there any option to generate links like appname.domain/pl/news/ when using scoped routes?
Thanks for help!
Your routes are scoped in a way, so that they can be called like this:
your.domain/pl/news
your.domain/en/news
if this pleases your aesthetics.
So, in other word, yes.
Have a look here, on how to use and set this:
http://guides.rubyonrails.org/i18n.html#setting-and-passing-the-locale
I have my routes set up as
scope "/admin" do
resources :profiles
end
So I am getting the expected routes with /admin/profiles. I want to exclude the show action from having this prefix. Is there an easy way to do this? Every solution I saw in the docs was around nested resources, I'm sure I overlooked something though. Thanks!
I think
scope "/admin", do
resources :profiles, except: :show
end
is what you need.
see more at http://guides.rubyonrails.org/routing.html#restricting-the-routes-created
The goal is to create a URL like this for a GET, REST API:
/manager/someID/report
example: /manager/2/report
I can get it to show in rake routes if do it this way:
get 'manager/:id/report', to: 'report#show'
But in some weblogs I read, thats the way unskilled developers write their routes! and looks like the better way is to use "nested resources" so I am banging my head over desk to get nested resources working the same way...but no success
this is what I have written so far:
resources :manager, only: [:show] do
resources :report, only: [:show], controller: 'report' do
member do
## WAT ?!
end
end
end
First, you might want to consider reading different blogs if they're calling routes like that "unskilled".
What you proposed is actually fine considering it's a non-standard RESTful route, and maybe even preferable in some cases. If you want an alternative approach, you have a couple different options. I don't think any one is more right than the other, but I prefer the first because it takes up less vertical space.
resources :manager, only: [:show] do
get 'report' => 'report#show', on: :member
end
or
resources :manager, only: [:show] do
member do
get 'report' => 'report#show'
end
end