Rails 2: Model.find (1) genera un error de ActiveRecord cuando no existe la Id. 1

Estoy usando Rails 2.3.5 y en eso si le doy a Model.find(1) y si 1 no está en la base de datos, devuelve el error de ActiveRecord. ¿Debería devolver nil como en el caso de Model.find_by_column('..') ?

    Este es el comportamiento esperado. Creo que David lo explica mejor, así que aquí hay una cita de Ruby, S., Thomas, D. & Hansson, DH, 2009. Desarrollo web ágil con Rails , Tercera edición Tercera edición., Pragmatic Bookshelf (p.330) .

    Cuando usa un buscador manejado por claves primarias, está buscando un registro particular. Esperas que exista. Una llamada a Person.find (5) se basa en nuestro conocimiento de la tabla de personas. Queremos la fila con una identificación de 5. Si esta llamada no tiene éxito, si el registro con la ID de 5 ha sido destruido, estamos en una situación excepcional. Esto obliga a plantear una excepción, por lo que Rails plantea RecordNotFound.

    Por otro lado, los buscadores que usan criterios para buscar buscan una coincidencia. Entonces, Person.find (: first,: conditions => “name = ‘Dave'”) es el equivalente a decirle a la base de datos (como un recuadro negro) “Dame la fila de la primera persona que tiene el nombre Dave”. un enfoque claramente diferente a la recuperación; no estamos seguros por adelantado de que obtendremos un resultado. Es completamente posible que el conjunto de resultados esté vacío. Por lo tanto, devolver nil en el caso de buscadores que buscan una fila y una matriz vacía para buscadores que buscan muchas filas es la respuesta natural, no excepcional.

    Si realmente no desea la excepción, puede usar find_by_id :

     # @user = User.find(params[:id]) # original code @user = User.find_by_id(params[:id]) if @user # found! else # not found end 

    Esto debería ser más rápido que una exists? separada exists? comprobar.

    EDITAR: Tenga en cuenta que, como comentó @Miguelgraz, en Rails 4 debería decir User.find_by(id: params[:id]) . La misma funcionalidad, pero ahora la implementación no necesitará method_missing .

    lanzar la excepción es el comportamiento esperado.

    de hecho, en el curso normal de los eventos, si deja que la excepción no se controle, el servidor de sus raíles devolverá el error 404 página no encontrada correcta.

    si desea que devuelva nada, puede atraparlo usted mismo:

     begin @model = Model.find(id_provided) rescue ActiveRecord::RecordNotFound => e @model = nil end 

    Si desea que se arroje la excepción en find_by_attributes sabores de los métodos de búsqueda, puede usar el bang! versión del método.

    Por ejemplo,

     Model.find_by_category!(a_category_value) 

    lanzará RecordNotFound si no se encuentra ninguna coincidencia.

    Encontré esto como DRY en escenarios como los controladores RESTful, donde tengo un controlador de error común para la excepción y quiero que mis acciones se comporten de manera consistente cuando no se encuentra un recurso que coincida con los parámetros dados.

    Método Rails 4

     if user = User.find_by(id: params[:id]) #do something with user else #throw error or redirect raise ActiveRecord::RecordNotFound end 

    Puede verificar si el registro existe antes de ir a buscarlo.

     @model = Model.find(id) if Model.exists?(id) 

    Puede usar find_by con el atributo requerido (en su caso, el id) esto dará como resultado cero en lugar de dar un error si no se encuentra el id.

     Model.find_by_id(id_value) 

    También puede usar where, pero debe saber que donde devuelve una relación de registro activa con cero o más registros que necesita usar primero para devolver solo un registro o nulo en caso de que regresen cero registros.

     Model.where(id: id_value).first 

    Puedes simplemente usar:

     user = User.find(10) rescue nil