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)