Rails advises to keep controllers and its actions resourceful buy providing resourceful routes helpers to create routes with default CRUD actions. However, very often, we find ourselves in a situation where we need to add more actions to a controller than those that are provided by resourceful routes. Lets look at such an example and see how we can better address such situations.
class JobsController < ApplicationController def index ... end def show ... end end
In above example,
Job is a resource,
show actions are part of
basic CRUD operations.
Setting the routes for these actions is very simple in Rails with:
resource :jobs, only: [:index, show]
Now, we want to add an option for the users to get a shareable link for the job. This link is to be generated dynamically with tracking parameters to recognise the user who shared this job. This link is not required to be stored anywhere.
Its easy to think of adding a new action
shareable_link to the controller
and add a respective route:
resource :jobs, only: [:index, :show] do member do get 'shareable_link' end end
This is fine until we have many such extra actions in the controller. Our controller will quickly grow huge. The best way to deal with this is to rethink those actions and see if there can actually be their own resources.
Resources doesn’t have to be models.
Its a common misconception that resourceful routes in Rails are only for models.
In our above example, we don’t have a model that’s called
we can still see that as a resource nested under job.
We can simply create a new controller assuming
ShareableLink as a resource
and add a resourceful route as follows:
# app/controllers/shareable_links_controller.rb class ShareableLinksController < ApplicationController def create ... end end # config/routes.rb resource :jobs, only: [:index, :show] do resource :shareable_links, only: [:create] end
This way, we can keep our controllers more resourceful and lean making it easier to maintain them.
If we are adding too many actions to a controller that are not part of the basic resourceful route actions (index, create, show, update and delete), its best if we rethink those actions and see if they can be treated as different resources.
Also, a controller in Rails doesn’t have to be associated to an ActiveRecord model.