Reputation: 1577
I'm writing an API in ruby on rails, and I find that my methods are extremely repetitive. This is how almost all of my methods look like. They all follow a similar structure; I just grabbed one of my methods and placed it here:
def create
if current_user
@object = Object.new(object_params)
if @object.save
render json: {
status: "SUCCESS",
message: "object saved"
}, status: :ok
else
render json: {
status: "ERROR",
message: "Could not save object"
}, status: :unprocessable_entity
end
else
render json: {
status: "UNAUTHORIZED"
}, status: :unauthorized
end
end
Of course, not all of my methods create and save objects. But they all follow a similar pattern. first I check if the current_user
is not nil. If it is, I render a JSON response:
if current_user
# do something
else
render json: {
status: "UNAUTHORIZED"
}
if the current user is found, and whatever the method has to run is successful, then I will render another JSON response:
if everything_went_well
render json: {
status: "SUCCESS",
message: "Everything went ok!"
}
else
render json: {
status: "ERROR",
message: "There was a problem!"
}
end
I'm pretty sure there is a way to abstract this sort of functionality. I've looked up tips online that have helped but in other parts of the project (i.e., models and views). Most of the tips I've seen online, however, aren't very adaptable to the code I have in my controllers.
Upvotes: 2
Views: 171
Reputation: 5788
If all of you controllers look like that, then you can have a base controller, and have all other controllers inherit from that controller. This would make your code DRY.
So, your base controller would look something like this:
class API::BaseController < ApplicationController
protected
def check_permission
return if current_user
render json: {
status: "UNAUTHORIZED"
}, status: :unauthorized
end
def render_success
render json: {
status: "SUCCESS",
message: "object saved"
}, status: :ok
end
def render_error
render json: {
status: "ERROR",
message: "Could not save object"
}, status: :unprocessable_entity
end
end
Then in one of your controllers:
class API::OtherController < API::BaseController
before_filter :check_permission
def create
@object = Object.new(object_params)
if @object.save
render_success
else
render_error
end
end
end
You can also move the before_filter
part to the base controller, but that would be less flexible. With current setup, you have that filter only for some of your actions, say before_filter :check_permission, only: [:create]
.
But if you move the before_filter
to the base controller, you will lose that flexibility.
Upvotes: 0
Reputation: 106972
You can use a before_filter
for this. Note that when a before_action
already rendered a view that the action itself will not be called anymore.
before_action :check_permission
def create
@object = Object.new(object_params)
if @object.save
render json: {
status: "SUCCESS",
message: "object saved"
}, status: :ok
else
render json: {
status: "ERROR",
message: "Could not save object"
}, status: :unprocessable_entity
end
end
private
def check_permission
return if current_user
render json: {
status: "UNAUTHORIZED"
}, status: :unauthorized
end
Upvotes: 3