rails find_by ruby-on-rails rails-activerecord dynamic-finders

ruby on rails - rails - encontrar vs find_by vs donde



find() rails (10)

Además de la respuesta aceptada, seguir también es válido

Model.find() puede aceptar una matriz de identificadores y devolverá todos los registros que coincidan. Model.find_by_id(123) también acepta una matriz pero solo procesará el primer valor de identificación presente en la matriz

Model.find([1,2,3]) Model.find_by_id([1,2,3])

Soy nuevo en los rieles. Lo que veo es que hay muchas formas de encontrar un registro:

  1. find_by_<columnname>(<columnvalue>)
  2. find(:first, :conditions => { <columnname> => <columnvalue> }
  3. where(<columnname> => <columnvalue>).first

Y parece que todos terminan generando exactamente el mismo SQL. Además, creo que lo mismo es cierto para encontrar registros múltiples:

  1. find_all_by_<columnname>(<columnvalue>)
  2. find(:all, :conditions => { <columnname> => <columnvalue> }
  3. where(<columnname> => <columnvalue>)

¿Existe una regla general o recomendación sobre cuál usar?


Ambos # 2 en sus listas están siendo desaprobados. Sin embargo, todavía puede usar find(params[:id]) .

Generalmente, where() funciona en la mayoría de las situaciones.

Aquí hay una gran publicación: http://m.onkey.org/active-record-query-interface


Desde Rails 4 puedes hacer:

User.find_by(name: ''Bob'')

que es el equivalente find_by_name en Rails 3.

Use #where cuando #find y #find_by no son suficientes.


Hay una diferencia entre find y find_by en que find devolverá un error si no se encuentra, mientras que find_by devolverá null.

A veces es más fácil de leer si tienes un método como find_by email: "haha" , en lugar de .where(email: some_params).first .


La respuesta aceptada generalmente lo cubre todo, pero me gustaría agregar algo, solo en caso de que esté planeando trabajar con el modelo de una manera similar a la actualización, y está recuperando un solo registro (cuyo id no conoce), luego find_by es el camino a seguir, porque recupera el registro y no lo pone en una matriz

irb(main):037:0> @kit = Kit.find_by(number: "3456") Kit Load (0.9ms) SELECT "kits".* FROM "kits" WHERE "kits"."number" = ''3456'' LIMIT 1 => #<Kit id: 1, number: "3456", created_at: "2015-05-12 06:10:56", updated_at: "2015-05-12 06:10:56", job_id: nil> irb(main):038:0> @kit.update(job_id: 2) (0.2ms) BEGIN Kit Exists (0.4ms) SELECT 1 AS one FROM "kits" WHERE ("kits"."number" = ''3456'' AND "kits"."id" != 1) LIMIT 1 SQL (0.5ms) UPDATE "kits" SET "job_id" = $1, "updated_at" = $2 WHERE "kits"."id" = 1 [["job_id", 2], ["updated_at", Tue, 12 May 2015 07:16:58 UTC +00:00]] (0.6ms) COMMIT => true

pero si usa el where entonces no puede actualizarlo directamente

irb(main):039:0> @kit = Kit.where(number: "3456") Kit Load (1.2ms) SELECT "kits".* FROM "kits" WHERE "kits"."number" = ''3456'' => #<ActiveRecord::Relation [#<Kit id: 1, number: "3456", created_at: "2015-05-12 06:10:56", updated_at: "2015-05-12 07:16:58", job_id: 2>]> irb(main):040:0> @kit.update(job_id: 3) ArgumentError: wrong number of arguments (1 for 2)

en tal caso, debería especificarlo así

irb(main):043:0> @kit[0].update(job_id: 3) (0.2ms) BEGIN Kit Exists (0.6ms) SELECT 1 AS one FROM "kits" WHERE ("kits"."number" = ''3456'' AND "kits"."id" != 1) LIMIT 1 SQL (0.6ms) UPDATE "kits" SET "job_id" = $1, "updated_at" = $2 WHERE "kits"."id" = 1 [["job_id", 3], ["updated_at", Tue, 12 May 2015 07:28:04 UTC +00:00]] (0.5ms) COMMIT => true


Supongamos que tengo un modelo de usuario

  1. User.find(id)

Devuelve una fila señalada por el id. Supongamos que si id = 1, devolverá la primera fila. El tipo de devolución será un objeto Usuario.

  1. User.find_by(email:"[email protected]")

Devuelve la primera fila con el atributo o el correo electrónico correspondiente en este caso. El tipo de devolución será el objeto Usuario nuevamente.

  1. User.where(project_id:1)

Devuelve todos los usuarios en la tabla de usuarios donde coinciden los atributos. Aquí el tipo de devolución será una matriz de objetos de Usuario.


Utilice el que considere más adecuado para sus necesidades.

El método de find se usa generalmente para recuperar una fila por ID:

Model.find(1)

Otros usos del find generalmente se reemplazan con cosas como esta:

Model.all Model.first

Find_by se usa como ayuda cuando busca información dentro de una columna y se asigna a las convenciones de nomenclatura. Por ejemplo, si tiene una columna llamada name en su base de datos, usaría la siguiente sintaxis:

Model.find_by_name("Bob")

Sin embargo, creo que find_by está en desuso.

.where es más de una captura todo lo que le permite utilizar una lógica un poco más compleja para cuando los ayudantes convencionales no lo hacen.


Yo personalmente recomendaré usar

where(< columnname> => < columnvalue>)


Model.find

1- Parámetro: ID del objeto a encontrar.

2- Si se encuentra: Devuelve el objeto (Un solo objeto).

3- Si no se encuentra: genera una excepción ActiveRecord::RecordNotFound .

Model.find_by

1- Parámetro: clave / valor

Ejemplo:

User.find_by name: ''John'', email: ''[email protected]''

2- Si se encuentra: Devuelve el objeto.

3- Si no se encuentra: devuelve nil .

Nota: Si desea que ActiveRecord::RecordNotFound use find_by!

Model.where

1- Parámetro: igual que find_by

2- Si se encuentra: Devuelve ActiveRecord::Relation contiene uno o más registros que coinciden con los parámetros.

3- Si no se encuentra: ActiveRecord::Relation un Empty ActiveRecord::Relation .


donde devuelve ActiveRecord :: Relation

Ahora eche un vistazo a la implementación de find_by:

def find_by where(*args).take end

Como puede ver, find_by es igual que where, pero solo devuelve un registro. Este método se debe usar para obtener 1 registro y dónde se debe usar para obtener todos los registros con algunas condiciones.