This is mostly an api design question. I have a Rails api which has routes for Users and routes for Schools. I would like to make a single call from my front end application to the api with a param of UserId which returns all of the schools associated with that user.
What is the best way to do that? Should I create a new route in UsersController called user-schools? Or a new route in SchoolsController called schools-user? Or create an entirely new controller called user-schools? Thanks for any guidance!
PS: Getting the records from ActiveRecord in the controller is not the problem. The problem is how to best design this api.
The RESTful way to define this would be through a nested route:
GET /users/:user_id/schools
The same basic design principles apply here for API and "classic" applications.
You can define this by nesting the calls to the resources macro:
resources :users do
resources :schools, only: [:index]
end
This will route /users/:user_id/schools
to SchoolsController#index
. While you can "sniff" for the user_id
param:
class SchoolsController
# GET /schools
# GET /users/1/schools
def index
schools = if params[:user_id].present?
user = User.find(params[:user_id])
user.schools
else
School.all
end
render json: schools
end
end
A cleaner design is to use a seperate controller for the nested context:
resources :users do
resources :schools, only: [:index], module: :users
end
module Users
class SchoolsController < ApplicationController
# GET /users/1/schools
def index
user = User.find(params[:user_id])
render json: user.schools
end
end
end
This controller only does a single job. You could also name it UserSchoolsController
but splitting your controllers into folders (and namespaces) makes it easier to organize them.