Home > Software engineering >  How can i create a shallow route in rails?
How can i create a shallow route in rails?

Time:11-01

I have this routes in rails, other developer i made that

namespace :api do
    namespace :v1 do
      resources :articles do
        resources :posts
      end
    end
  end

now i want to test it by postman, but i dont understand how will be the url of the endpoint

i tested this url

http://localhost:3000/api/v1/articles?id=1&posts=1

but just i am getting this error

"#<ActionController::RoutingError: uninitialized constant Api::V1::ArticlesController\n\n 

CodePudding user response:

You can type rails routes to print all routes you have defined so far. Then you'll know what the routes URL should be looked like

In your example, it should be like GET api/v1/articles/1/posts/1.

CodePudding user response:

You can open localhost:3000/routes to view and search your route helper paths and urls

CodePudding user response:

When you nest a route in Rails the "parent" resource is added to the path as a static segment and a dynamic segment consisting of the parent id:

/api/v1/articles/:article_id/posts/:id

You can display the routes in your app with the rails routes command or visiting http://localhost:3000/routes in newer versions of Rails.

This is basically a regular expression on steroids which the incoming request URI is matched against.

Query string parameters are not used for matching routes in which is why http://localhost:3000/api/v1/articles?id=1&posts=1 is being routed to ArticlesController#index since it matches /api/v1/articles.

In general in Rails flavor REST query string parameters are merely used for additional information such as paging or filtering. Not for routing to resources.

If you wanted to declare this as a shallow route you pass the shallow option to the resources macro:

namespace :api do
  namespace :v1 do
    resources :articles do
      resources :posts, shallow: true
    end
  end
end

This will generate the member route /api/v1/posts/:id for a single post while the collection routes (new, index, create) are still nested.

max@maxbook ~/p/sandbox_7 (main)> rails routes | grep posts
                    api_v1_article_posts GET    /api/v1/articles/:article_id/posts(.:format)                                                      api/v1/posts#index
                                         POST   /api/v1/articles/:article_id/posts(.:format)                                                      api/v1/posts#create
                 new_api_v1_article_post GET    /api/v1/articles/:article_id/posts/new(.:format)                                                  api/v1/posts#new
                        edit_api_v1_post GET    /api/v1/posts/:id/edit(.:format)                                                                  api/v1/posts#edit
                             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

This option is also "inherited" so you can pass it to the parent resource to make all the nested routes shallow:

namespace :api do
  namespace :v1 do
    resources :articles, shallow: true do
      resources :posts
      resources :photos
      resources :videos
    end
  end
end

CodePudding user response:

The error suggests that you have not yet created a controller that corresponds to the route.

Folder structure: app/controllers/api/v1/posts_controller.rb

class Api::V1::PostsController
end
  • Related