2012-03-05 14 views
69

Me he dado cuenta de que el método Model.where siempre devuelve una matriz, incluso si solo hay un resultado donde no lo hace el método Model.find. Hay alguna razón para esto? Pensé que Model.where era la función preferida desde Rails 3.X.Rails .where vs .find

¿Debo utilizar Model.find cuando espero un único resultado y Model.where cuando espero más de un resultado?

Respuesta

109
  • where devuelve un ActiveRecord::Relation (no una matriz, a pesar de que se comporta como una), que es una colección de los objetos del modelo . Si nada coincide con las condiciones, simplemente devuelve una relación vacía.

  • find (y sus afines find_by_columnname métodos dinámicos) Devuelve un objeto modelo sola. Si no se encuentra nada, se genera una excepción ActiveRecord::RecordNotFound (pero no con los métodos dinámicos find_by_).

    Mientras find puede devolver una matriz de registros-no una relación de si se le da una lista de ID, utilizando where se prefiere ya Rails 3. Muchos usos similares de find son ahora deprecated or gone entirely.

Así que sí, si sólo quiere y espera un único objeto, utilizando find es más fácil, ya que de lo contrario debe llamar Model.where.first.

Tenga en cuenta que las opciones antiguas de hash find y muchos métodos dinámicos find_ están en desuso a partir de Rails 4.0 (see relevant release notes).

+0

pienso que 'find' puede devolver varios objetos en una matriz - tratar' User.find [1,2,3 ] '(encuentra usuarios con ids 1, 2 y 3) ... pero sí, supongo que andrew tiene razón sobre el resto – klump

+3

@klump Sí, puede, pero' User.where (id: [1, 2, 3]) 'es preferido en ese caso, así que ni siquiera lo consideré. Como siempre, recomiendo leer la documentación de la API (a la que me he vinculado en mi respuesta), ya que proporciona la mayor cantidad de detalles. –

+0

Pero '.find (: all, ...)' devuelve una matriz. Entonces, ¿cuál es la diferencia entre encontrar y dónde? – highBandWidth

6

Model.find está utilizando la columna de la clave principal. Por lo tanto, siempre hay exactamente uno o ningún resultado. Úselo cuando esté buscando un elemento específico identificado por su id.

+7

No si lo haces '.find (: conditions => {: col_name => some_vals})'. – highBandWidth

+0

O si usamos el default_scopes entonces puede considerar otros valores también ... –

12

realidad find_by toma un objeto de modelo de where obtiene ActiveRecord::Relation

def find_by(*args) 
    where(*args).take 
end 

Source

+4

Tenga en cuenta que find_by no se agregó hasta Rails 4 (la pregunta original fue etiquetada rails 3). – Steve

Cuestiones relacionadas