Rails 3 Resource: Share Custom Actions with Nested Resources - ruby-on-rails

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

Related

Add rails routing concerns before the resource

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.

Appropriately nest resources in routes.rb

My application has deeply nested resources, but after reading http://guides.rubyonrails.org/routing.html#shallow-nesting, I've realized it's not wise to have these deeply nested resources. Here is the situation my routes are currently in.
resources :assortments do
resources :comments do
member do
post :like
post :unlike
end
end
member do
post :like
post :unlike
end
resources :designs do
resources :comments do
member do
post :like
post :unlike
end
end
member do
post :like
post :unlike
get :likes
end
end
end
I want to know the proper way to organize this structure to make it less confusing and "proper". Or is what I have ok?
Thanks.
you could just specify the shallow: true on your top resources :assortments and should build shallow routes for all the nested routes automatically.
I also would move the :comments resource into a concern, kind of like that
concern :commentable do
resources :comments do
member do
:like
:unlike
end
end
end
resources :assortments, shallow: true do
concerns :commentable
...
resources :designs do
concerns :commentable
end
end
And on an unrelated topic, i'd consider making the LikesController to have a centralized likes handling resource, might save one some headache when you have polymoriphic liking thing going on.

rails routing nested resources duplicate

I want to support:
POST images/1/comments/2/like
and
POST comments/2/like
They both point to same resources with same action. How can I do that in rails route file?
resources :images do
resources :comments do
member do
post 'like'
end
end
end
This will work for
POST images/1/comments/2/like
but how can I also for when I don't specify the images/1 part?
You can make it more beautiful actually. According to http://ruby-journal.com/how-to-dry-your-rails-routes/, this also works:
comments = Proc.new do
member do
post 'like'
end
end
resources :comments, &comments
resources :images do
comments.call
end
and in Rails 4 you could use concerns
concern :comments_concern do
member do
post 'like'
end
end
resources :comments, concerns: :comments_concern
resources :images, concerns: :comments_concern do
#do more stuff here
end
I didn't test this, but it might help. Have a look at the website mentioned. Good luck
-frbl
I would consider reworking which RESTful routes for Comment you're nesting, and which you're not. I'm assuming your models look something like this:
# app/models/image.rb
class Image < ActiveRecord::Base
has_many :comments
end
# app/models/comment.rb
class Comment < ActiveRecord::Base
belongs_to :image
end
Because your Image and Comment models possess a one-to-many relationship, I can see why you'd think to nest the comments resource route within the images one. However, of all the CRUD actions in comments_controller.rb, only create actually requires that a parent image ID be explicitly passed in. From a RESTful perspective, only the new and create actions require that a image_id is passed to the action. The edit, update, delete, and like actions can all take place independently of the parent image.
Consider the alternative routing schematic instead:
# config/routes.rb
resources :images do
resources :comments, :only => [:index, :new, :create]
end
resources :comments, :only => [:show, :edit, :update, :destroy] do
member do
post 'like'
end
end
Now, only the comment actions that are explicitly depended on a parent ID are actually nested within the images routes. The remainder of the comment actions are directly routed to the comments controller without passing in the parent ID. Your routes are no longer duplicated, and each action will have exactly one route declared for it.
simply add resources :images it may work
Not sure there is a much more beautiful way than repeating this below:
resources :comments do
member do
post 'like'
end
end
Like so:
resources :images do
resources :comments do
member do
post 'like'
end
end
end
resources :comments do
member do
post 'like'
end
end

Rails 3 create a route to nested independent page

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

Creating a specific custom route in rails 3

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

Resources