Rails Routes Format - ruby-on-rails

Need to generate the following routes as
/:owner_name/articles
/:articles/:id
/owners
/:owner_name
I have tried as,
resources :owners, param: :owner_name, path: '', shallow_path: "", only: [:index, :show] do
resources :articles, only: [:index,:show]
end
But I am not able to reproduce the same

Maybe it is not the best solution but you can try the following
resources :articles, only: :show
resources :owners, only: :index
resources :owners, param: :name, path: '', only: :show do
resources :articles, only: :index
end
It produces
Prefix Verb URI Pattern Controller#Action
article GET /articles/:id(.:format) articles#show
owners GET /owners(.:format) owners#index
owner_articles GET /:owner_name/articles(.:format) articles#index
owner GET /:name(.:format) owners#show
UPDATE
The code above has :name parameter instead of :owner_name for owners#show route (if it does matter for you).
You can try to specify parameters manually like
resources :articles, only: :show
resources :owners, only: :index
get '/:owner_name', to: 'owners#show'
get '/:owner_name/articles', to: 'articles#index'
It will give you
Prefix Verb URI Pattern Controller#Action
article GET /articles/:id(.:format) articles#show
owners GET /owners(.:format) owners#index
GET /:owner_name(.:format) owners#show
GET /:owner_name/articles(.:format) articles#index

Related

Renaming rails route parameter to id

In my routes.rb file, I have the following resources
resources :classrooms, only: [:index, :new, :create] do
resources :students, only: [:index, :edit, :update], controller: 'students' do
get :honor
end
end
My honor route becomes /classrooms/:classroom_id/students/:students_id/honor(.:format)
but I want to replace student_id to id so that I can easily use it in the students controllers.
Ideal route is /classrooms/:classroom_id/students/:id/honor(.:format)
You can do that specifying it's a member route. this way
get :honor, on: :member
or
member do
get :honor
end

How to name nested routes parameters in Rails?

I've the following nested route:
resources :carts, only: [:show, :update, :create], param: :token do
resources :items, :controller => :cartitems, except: [:new, :edit], param: :product_id
end
This generates
GET /api/merchants/:merchant_id/carts/:cart_token/items(.:format) cartitems#index
POST /api/merchants/:merchant_id/carts/:cart_token/items(.:format) cartitems#create
GET /api/merchants/:merchant_id/carts/:cart_token/items/:product_id(.:format) cartitems#show
PATCH /api/merchants/:merchant_id/carts/:cart_token/items/:product_id(.:format) cartitems#update
PUT /api/merchants/:merchant_id/carts/:cart_token/items/:product_id(.:format) cartitems#update
DELETE /api/merchants/:merchant_id/carts/:cart_token/items/:product_id(.:format) cartitems#destroy
...
I want to remove the controller part in the resources :items parameters. That means: I want to rename the :cart_token parameter to :token. Just like:
GET /api/merchants/:merchant_id/carts/:token/items(.:format) cartitems#index
POST /api/merchants/:merchant_id/carts/:token/items(.:format) cartitems#create
GET /api/merchants/:merchant_id/carts/:token/items/:product_id(.:format) cartitems#show
PATCH /api/merchants/:merchant_id/carts/:token/items/:product_id(.:format) cartitems#update
PUT /api/merchants/:merchant_id/carts/:token/items/:product_id(.:format) cartitems#update
DELETE /api/merchants/:merchant_id/carts/:token/items/:product_id(.:format) cartitems#destroy
...
How can this be achieved?
Don't know if it's the best way to do that, but I got the routes you expected there by:
scope 'api/mechantes/:merchant_id/carts/:token' do
resources :items, :controller => :cartitems, except: [:new, :edit], param: :product_id
end
Hope this can helps. Good luck!

rails - how to target nested controller for nested resource route

In my routes.rb I have
namespace :admin do
resources :clients do, only: [:index] do
resources :products, only: [:index, :new, :create]
end
resources :products, only: [:index]
end
Notice that I have two lines for resources :products. One is nested within resources :clients and the other as a top-level resource on :admin; each of these two has a different purpose in the application.
rake routes gives me:
admin_clients GET /admin/clients(.:format) admin/clients#index
admin_client_products GET /admin/clients/:client_id/products(.:format) admin/products#index
POST /admin/clients/:client_id/products(.:format) admin/products#create
new_admin_client_product GET /admin/clients/:client_id/products/new(.:format) admin/products#new
admin_products GET /admin/products(.:format) admin/products#index
I have a admin_client_products for the nested product#index resource. I also have admin_products for the top-level product#index resource. However, they point to the same controller action: admin/product#index.
Question: At this point, I need rails to deduce that these are two different actions. Using rails conventions, is there a way to tell rails that these two resources should have different controller actions i.e. one that should hit admin/products#index and the other should hit admin/clients/products#index?
The nested route should hit this:
class Admin::Clients::ProductsController < Admin::BaseController
def index; end
end
The top-level route should hit this:
class Admin::ProductsController < Admin::BaseController
def index; end
end
Definitely you can!
Here you need to customize your resourceful route by explicitly specifying a controller to use for the resource. The :controller option will let you do that.
So, in your case, specifying the controller as clients/products for the admin_clients_products resource would work in your desired way.
namespace :admin do
resources :clients, only: [:index] do
resources :products, only: [:index, :new, :create], controller: 'clients/products'
end # ------------------------------
resources :products, only: [:index]
end
rails routes will now give you what you want:
admin_client_products GET /admin/clients/:client_id/products(.:format) admin/clients/products#index
POST /admin/clients/:client_id/products(.:format) admin/clients/products#create
new_admin_client_product GET /admin/clients/:client_id/products/new(.:format) admin/clients/products#new
admin_clients GET /admin/clients(.:format) admin/clients#index
admin_products GET /admin/products(.:format) admin/products#index
=========================
Extra bits:
If you want to omit the /admin portion from the url (I mean, if your application's routing design permits to), then you could use: scope module: 'admin' do...end like the following:
scope module: 'admin' do
resources :clients, only: [:index] do
resources :products, only: [:index, :new, :create], controller: 'clients/products'
end
resources :products, only: [:index]
end
and suddenly your routes will start looking awesome :)
client_products GET /clients/:client_id/products(.:format) admin/clients/products#index
POST /clients/:client_id/products(.:format) admin/clients/products#create
new_client_product GET /clients/:client_id/products/new(.:format) admin/clients/products#new
clients GET /clients(.:format) admin/clients#index
products GET /products(.:format) admin/products#index

Static nested resource params name on Rails routes

I'm playing on Rails routing but I can't figure out how to manage this. The problem is at user_posts(1) and user(4) routes, the params have different names - id and user_id
What I'm trying to achieve is a static param name for the same resource.
I have this route file
Rails.application.routes.draw do
shallow do
resources :users, module: :users, only: [:index, :show] do
resources :posts, module: :posts, only: [:index, :show]
end
end
end
The routes generated are
user_posts(1) GET /users/:user_id/posts(.:format) users/posts/posts#index
post(2) GET /posts/:id(.:format) users/posts/posts#show
users(3) GET /users(.:format) users/users#index
user(4) GET /users/:id(.:format) users/users#show
I tried resources :user param: :user but the generated route at user_posts is /users/:user_user_id/posts
Is possible to achieve a :user_id param and :post_id param for every route using resources?
Try this
resources :users, param: :user_id
resources :users, only: [] do
resources :posts, param: :post_id
end
It is not possible 'cause it is useless. Your only option is to nest post into the user resources in such manner:
resources :users, only: [:index, :show] do
resources :posts, only: [:index, :show]
end

Nesting APIs routes

Im trying to create API endpoints from my Post model . It should be able to read, update, delete and create posts.
But a post needs to be assosiated to a Topic in order for it to be created so i nested it under topics. Here are my routes
namespace :api do
namespace :v1 do
resources :users, only: [:index, :show, :create, :update]
resources :posts, only: [:show, :update, :destroy]
resources :topics, except: [:edit, :new] do
resources :posts, only: [:create]
end
end
end
api_v1_post GET /api/v1/posts/:id(.:format) api/v1/posts#show
PATCH /api/v1/posts/:id(.:format) api/v1/posts#update
PUT /api/v1/posts/:id(.:format) api/v1/posts#update
DELETE /api/v1/posts/:id(.:format) api/v1/posts#destroy
api_v1_topic_posts POST /api/v1/topics/:topic_id/posts(.:format) api/v1/posts#create
api_v1_topics GET /api/v1/topics(.:format) api/v1/topics#index
POST /api/v1/topics(.:format) api/v1/topics#create
api_v1_topic GET /api/v1/topics/:id(.:format) api/v1/topics#show
PATCH /api/v1/topics/:id(.:format) api/v1/topics#update
PUT /api/v1/topics/:id(.:format) api/v1/topics#update
DELETE /api/v1/topics/:id(.:format) api/v1/topics#destroy
my issue is im getting a "no routes match" error when i run my Rspec
I think the issue is with the relationship.
Please add the relationship between Topic and Post and then try.
class Topic < ActiveRecord::Base
has_many :posts
end
class Post < ActiveRecord::Base
belongs_to :topic
end
If the route you are trying to create is POST api/v1/topics/:topic_id/create_post going to TopicsController than you would want the nesting to look like this instead:
resources :topics, except: [:edit, :new] do
post 'create_post' => 'topics#create_post'
end
Try this out for creating your routes if you haven't had success yet. It should provide the output that you want.
resources :topics, except: [:edit, :new] do
collection do
post 'create_post'
end
end

Resources