Add rails routing concerns before the resource - ruby-on-rails

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.

Related

Rails nested resources ignore single route

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

Rails routing issue: Unwanted route

I have a Ruby on Rails project. In my config/routes.rb, I have the following setup:
scope module: :comments do
resources :tasks do
resources :comments, only: %i[index]
end
end
This creates the route that I want in rake routes:
v1_task_comments GET /v1/tasks/:task_id/comments(.:format) v1/comments/comments#index
but it also creates the following route, which is wrong and which I don't want:
v1_tasks GET /v1/tasks(.:format) v1/comments/tasks#index
How do I create the first route without generating the second?
You can use the only option of resources routes helper:
resources :tasks, only: :none do
# ...
end

Nested Routing - current_user in URL

I have to models User and Blog. Their respective urls are:
test.com/u/user_name # User
test.com/blogs # Blog
I'm trying to achieve that the blogs are nested to the user which created it. E.g. test.com/u/user_name/blogs and for an article test.com/u/user_name/blogs/article_name.
But the index for all blogs should respond to: test.com/blogs.
right now my routes are like this:
resources :users do
resources :blogs, except: [:index]
end
resources :blogs, only: [:index]
Which doesn't work.. What am i missing?
Routes
#config/routes.rb
resources :blogs, only: :index #-> domain.com/blogs -> blogs#index
resources :users, path: "u" do #-> domain.com/u/:id
resources :blogs #-> domain.com/u/:user_id/blogs/:id
end
You'll want to look up about the path argument for your routes
As a rule of thumb, you'll want to include any "non conventional" paths at the bottom of the routes file. As the routes are determined from the top to bottom, if you're capturing obscure paths near the top of the file, you'll end up causing conflict with your other routes

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

Adding a Route to the base URL of plural Resources

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

Resources