开发者

Why don't people wrap begin/rescue blocks around ActiveRecord.find in Rails?

开发者 https://www.devze.com 2023-01-09 06:02 出处:网络
If a user tries to submit a form or access a service that uses something such as the following underneath the hood:

If a user tries to submit a form or access a service that uses something such as the following underneath the hood:

Model.find(params[:id]) # if model does not exist, throw ActiveRecord::RecordNotFound

If an instance cannot be found, an exception is thrown. Yet I rarely see folks wrap that statement around in a begin/rescue block, even if you create a scaffold, the rails generator does not wrap the find call in开发者_如何学编程 begin/rescue blocks.

Is there a reason for that?


I think it's because the most common case is that if you're going after an object by id and it doesn't exist then that is exceptional. The exception will bubble up and rails will handle it as a 404 for you which is usually appropriate.

If it is a situation where the object may or may not exist then either catching the exception or using Model.find_by_id(params[:id]) and checking for a nil object work perfectly well.


One reason may be that error handling logic is passed to rescue handlers in the application.

your controller:

def some_action
  @foo = Foo.find!(params[:id])
  # Exception will raise here ...
  # ...
end

and then specify

rescue_from ActiveRecord::RecordNotFound, :some_method_that_will_render_a_404

(See this for an explanation)

Scaffolds are just shortcuts to get something up-and-running in a short time, but as a rule of thumb scaffolds are not meant to live up to production.

Personally, I've not seen too much code that doesn't do at least basic validation. I'd say it's somewhat a cultural thing: if you don't create a route that would raise an error, you are not obligated to handle it. Obviously this is far from ideal, but I think is not of a priority for many developers. This mainly depends on the business logic: it is usually positively oriented, that is, only contemplates responding to user valid actions.


because it's easier to call:

Model.find_by_id(params[:id])

Which returns nil if no record found


Because you want to fail early. The sooner you find out something's wrong, the sooner you can fix it.


I have seen code like that:

def add_to_cart
  begin
    product = Product.find(params[:id])
  rescue ActiveRecord::RecordNotFound
    logger.error("Attempt to access invalid product #{params[:id]}")     
    redirect_to_index("Invalid product")
  else
    @cart = find_cart
    @cart.add_product(product)      
  end
end
0

精彩评论

暂无评论...
验证码 换一张
取 消