i want to create a route to search an article
should be able to add the size or the page
like this
'/post/1/article/search?size=200&page=1
it will be good like this?
get '/post/:id/article/search/:size/:page
can i create that endpoint directly with rails?
namespace :api do
namespace :v1 do
resources :posts do
resources :articles
get /search/:size/:page
Something like this should work:
namespace :api do
namespace :v1 do
resources :posts do
resources :articles do
collection do
get "/search/:size/:page", action: :search, defaults: { size: 200, page: 1 }
end
end
end
end
end
In your controller, you'll be able to access via: params[:size] and params[:page].
NOTES 👀
If you just need to send as regular parameters ?size=200&page=1, you don't need to define the parameters in the route itself. The "querystring" was always sent to Rails controllers:
collection do
get :search
end
The defaults are not mandatory, but in such case I think it's a good idea as you will always have a fallback value for those parameters.
You can read further details in the official guides:
"collection" routes: https://guides.rubyonrails.org/routing.html#adding-collection-routes
"non-resourceful" routes: https://guides.rubyonrails.org/routing.html#non-resourceful-routes
Related
I've been trying rails and I found myself with a very simple problem: I have two models, survivors and locations, and they're nested resources in routes.rb
Rails.application.routes.draw do
namespace 'api' do
namespace 'v1' do
resources :survivors do
resources :locations
end
resources :abduction_reports
end
end
end
which gives me almost all the routes I need. The problem is that survivors and locations is one-to-one association, so if I want to update the survivor location, it seems more interesting if the end-point for that is
PUT /survivors/:survivor_id/location
To solve it, I did this:
Rails.application.routes.draw do
namespace 'api' do
namespace 'v1' do
[...]
put 'survivors/:survivor_id/location', to: 'locations#update'
end
end
end
but it doesn't seem the correct way to do it... I mean, can it be defined inside the 'resources :survivors do ... end' scope?
I probably have already seen it in the rails documentation, but I think I just haven't realized how to adapt the documentation examples to my problem yet.
For a singular resource use the resource macro instead:
Rails.application.routes.draw do
namespace 'api' do
namespace 'v1' do
resources :survivors do
resource :location
end
resources :abduction_reports
end
end
end
Prefix Verb URI Pattern Controller#Action
api_v1_survivor_location POST /api/v1/survivors/:survivor_id/location(.:format) api/v1/locations#create
new_api_v1_survivor_location GET /api/v1/survivors/:survivor_id/location/new(.:format) api/v1/locations#new
edit_api_v1_survivor_location GET /api/v1/survivors/:survivor_id/location/edit(.:format) api/v1/locations#edit
GET /api/v1/survivors/:survivor_id/location(.:format) api/v1/locations#show
PATCH /api/v1/survivors/:survivor_id/location(.:format) api/v1/locations#update
PUT /api/v1/survivors/:survivor_id/location(.:format) api/v1/locations#update
DELETE /api/v1/survivors/:survivor_id/location(.:format) api/v1/locations#destroy
api_v1_survivors GET /api/v1/survivors(.:format) api/v1/survivors#index
POST /api/v1/survivors(.:format) api/v1/survivors#create
new_api_v1_survivor GET /api/v1/survivors/new(.:format) api/v1/survivors#new
edit_api_v1_survivor GET /api/v1/survivors/:id/edit(.:format) api/v1/survivors#edit
api_v1_survivor GET /api/v1/survivors/:id(.:format) api/v1/survivors#show
PATCH /api/v1/survivors/:id(.:format) api/v1/survivors#update
PUT /api/v1/survivors/:id(.:format) api/v1/survivors#update
DELETE /api/v1/survivors/:id(.:format) api/v1/survivors#destroy
See:
https://guides.rubyonrails.org/routing.html#singular-resources
I have a blog with root
root 'posts#index'
And works best with example.com/ to example.com/posts
But what I want is something like this:
example.com/blog/posts/1.
I've tried creating blog Controller and add
resources :blog do
resources :posts
end
But this is making my routes to blog/:id/posts/:id
If you don't have the relationship between the post and the blog as you mentioned, rails gives you the freedom to declare routes as our own.
so, to make the route example.com/posts/1 to, example.com/blog/posts/1, just add a custom route at the last.
get '/blog/posts/:id', to: :show, controller: 'posts'
what this does is over rides the previous route and make this route final.
Now type rake routes and it will give the last route for you as,
GET /blog/posts/:id(.:format) posts#show
Now you can access using,
example.com/blog/posts/1
Reference for rails routing
Just to expand upon #Sravan answer. If you have multiple routes that will start with /blog/ you might want to check Rails guide on routing.
You can add something along the lines of
scope '/blog' do
resources :posts
resources :users
resources :images
end
Which will create corresponding routes under /blog/.
namespace :blog do
resources :posts
resources :users
resources :images
end
And your controller with namespace will look like this: Blog::PostsController
I would like to create a resourceful route on a resource member, but I can't seem to find the syntax to create the named route that I want.
namespace :admin
resources :foobars do
get :attribute, on: :member, as: :attribute
end
end
This will provide a route method called:
attribute_admin_foobar_path
I would like it to say:
admin_foobar_attribute_path
The only other way I can think of would be to reject the resources block and create a single route:
namespace :admin
resources :foobars
get 'foobars/:id/attribute', as: :foobar_attribute
end
However, I don't like this approach because it forces me to duplicate the routing structure of already existing routes...not very DRY.
Is there a way that I can create the route name that I want while still using the resources routing block?
If you do it like this:
namespace :admin do
resources :foobars do
get :attribute
end
end
You will get:
admin_foobar_attribute GET /admin/foobars/:foobar_id/attribute(.:format) admin/foobars#attribute
That is admin_foobar_attribute_path.
I currently have these routes set up:
namespace :api do
namespace :v1 do
resources :users do
match 'api/v1/users/all'
end
resources :sessions
end
end
I'm trying to set up a custom actio nin my users controller called "all".
How do I get the route for that to match? I've tried these, and get no route errors:
resources :users do
match 'api/v1/users/all' => "users#all" (also "api/v1/users#all" and "api_v1_users#all"
end
What is the route that will enable me to connect with my custom action?
Thanks
You need to add a collection
namespace :api do
namespace :v1 do
resources :users do
collection do
get 'all'
end
end
resources :sessions
end
end
The namespace and resources method calls create the hierarchy; a route nested with the resource :users block will take on the path of it's ancestors. The collection creates nested routes on the resource collection instead of single instances of the resource.
/api/v1/users/all
Recommended Reading: http://guides.rubyonrails.org/routing.html#adding-collection-routes
Actually I don't understand how to correctly handle this. I have a situation where news could be managed with admin/edit admin/show admin/news... and similar paths, however I want to give users a page called news/show/1, because actually my news resources are routed under "admin" namespace, how should I handle the fact that I need to bind news routes outside "admin" namespace?
Actually I have only this:
namespace :admin do
resources :news
end
My Idea:
namespace :admin do
resources :news
end
resources :news
Then I'll have:
app/controllers/admin/news_controller.rb
app/controllers/news_controller.rb
Is this correct?
Seeing your answer, I can suggest more simpler routes.
#routes.rb
namespace :admin do
resources :news
end
resources :news, :only => [:show]
If you want index action too, rewrite the last line as:
resources :news, :only => [:index, :show]
You won't need the helper for news_path and news_url. You will get them already built for you.
Ok after working a bit on routes, I understood how to build what I wanted:
namespace :admin do
resources :news
end
get 'news/:id(.:format)' => 'news#show'
This because I don't need all routes for my news, but only show (well I may add index too, but not required at the moment). In this way I can handle everything on 2 different controllers, which is better, because I use somethings like redirects on the news controller which I don't use on Admin::NewsController.
I noticed another important thing, if you build routes in this way news_path and news_url won't be created. Because of this, I had to manually create them in this way in news_helpers:
module NewsHelper
def news_url(record)
url_for controller: 'news', action: 'show', only_path: false, id: record.slug
end
def news_path(record)
url_for controller: 'news', action: 'show', only_path: true, id: record.slug
end
end
(slug is for seo-friendly urls) Then I simply included the helper in my controller in this way:
class NewsController < ApplicationController
include NewsHelper
Everything is worked as I wanted and looks great too.