The most important parts of a web page application is returning information to the user while providing errors in order for a better understanding of why a problem is occurring when a user is interacting throughout the app. Through the application controllers, CRUD(Create, Read, Update, Destroy) methods are developed in order for the front-end to interact with the database created in the back-end.
.find vs .find_by
When creating the create
, show
, and update
routes, the id of the data being displayed must be found. If the id cannot be found, an error will occur. For example, lets say we have a show methods in a movie controller:
class MoviesController < ApplicationController
def show
movie = Movie.find_by(id: params[:id])
if movie
render json: movie, status: :ok
else
render json: {error: "Movie not found"}, status: :not_found
end
end
end
By using .find_by
, the return value is nil
if the movie cannot be found. Therefore, an if/else
statement needs to be formulated in order to generate an error that will be used to display to the user.
We can also use a rescue
that ruby provides that can take the exception and use it as the error, replacing the if/else
statement for a more DRY approach:
class MoviesController < ApplicationController
def show
movie = Movie.find_by(id: params[:id])
render json: movie, status: :ok
rescue ActiveRecord::RecordNotFound
render json: {error: "Movie not found"}, status: :not_found
end
end
But there is an even DRY-er way for handling errors. If we use the .find
method, ActiveRecord returns an exception that contains a more detailed error. For example, if we make a fetch request to localhost:3000/movies/99
, the exception will look like:
ActiveRecord::RecordNotFound (Couldn't find Movie with 'id'=99)
We can use this exception to generate our error and apply it to every controller with a RecordNotFound
error but writing our rescue in the ApplicationController
:
class ApplicationController < ActionController::API
rescue_from ActiveRecord::RecordNotFound, with: :record_not_found
private
def record_not_found(error)
render json: {error: error.message}, status: :not_found
end
end
Since the error is being handled inside our "top" controller, the methods in the MoviesController
do not need to contain errors and therefore create a more DRY form:
class MoviesController < ApplicationController
def show
movie = Movie.find(params[:id])
render json: movie, status: :ok
end
end
Top comments (0)