I've found that both methods work for saving data. Is there an advantage to using one method over the other? What are the advantages/disadvantages?
First version:
begin
@user.save!
render json: "User #{@user.email} added", status: :created
rescue StandardError => e
render json: @user.errors.full_messages, status: :unprocessable_entity
end
Second version:
if @user.valid?
@user.save!
render json: "User #{@user.email} added", status: :created
else
render json: @user.errors.full_messages, status: :unprocessable_entity
end
I would go with a third alternative, because on save, the model is validated automatically:
if @user.save
render json: "User #{@user.email} added", status: :created
else
render json: @user.errors.full_messages, status: :unprocessable_entity
end
Its comes down to performance. Your first approach is more expensive because the full call stack has to be unwound to construct the exception details and you don't even use it.
When you catch an exception, the exception has the full stack trace where exactly the error occurred and what was the sequence of method calls that led to that event. Building this information requires Ruby to go to the previous method call and then to the previous-to-previous method call and so on recursively. This is a fairly expensive operation and since you are already within the method, you don't really need this information.
So, out of your two approaches, the second version is better. However jvperrin's answer is even better. In your second approach, you call @user.isvalid? which runs through all the model validations. And when you call @user.save, it again runs through the same validations. Instead you could just call @user.save directly and look at the return value, which is true when everything went well and false when there were validation errors.
Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With