Cómo seleccionar dónde ID en Array Rails ActiveRecord sin excepción
-
10-07-2019 - |
Pregunta
Cuando tengo una variedad de identificadores, como
ids = [2,3,5]
y realizo
Comment.find(ids)
todo funciona bien. Pero cuando hay una identificación que no existe, obtengo una excepción. Esto ocurre generalmente cuando obtengo una lista de ID que coinciden con algún filtro y luego hago algo como
current_user.comments.find(ids)
Esta vez es posible que tenga una ID de comentario válida, que sin embargo no pertenece al Usuario dado, por lo que no se encuentra y obtengo una excepción.
He intentado find (: all, ids)
, pero devuelve todos los registros.
La única forma en que puedo hacerlo ahora es
current_user.comments.select { |c| ids.include?(c.id) }
Pero eso me parece una solución súper ineficiente.
¿Hay una mejor manera de seleccionar ID en la matriz sin obtener una excepción en el registro no existente?
Solución
Si solo está evitando la excepción que le preocupa, el " find_all_by .. " la familia de funciones funciona sin lanzar excepciones.
Comment.find_all_by_id([2, 3, 5])
funcionará incluso si algunos de los identificadores no existen. Esto funciona en el
user.comments.find_all_by_id(potentially_nonexistent_ids)
caso también.
Actualización: Rails 4
Comment.where(id: [2, 3, 5])
Otros consejos
Actualización: esta respuesta es más relevante para Rails 4.x
Haz esto:
current_user.comments.where(:id=>[123,"456","Michael Jackson"])
El lado más fuerte de este enfoque es que devuelve un objeto Relation
, al que puede unir más cláusulas .where
, .limit
cláusulas, etc., lo cual es muy útil. También permite identificaciones inexistentes sin generar excepciones.
La sintaxis más nueva de Ruby sería:
current_user.comments.where(id: [123, "456", "Michael Jackson"])
Si necesita más control (quizás necesite indicar el nombre de la tabla), también puede hacer lo siguiente:
Model.joins(:another_model_table_name)
.where('another_model_table_name.id IN (?)', your_id_array)
Ahora los métodos .find y .find_by_id están en desuso en los rieles 4. Por lo tanto, podemos usar a continuación:
Comment.where(id: [2, 3, 5])
Funcionará incluso si algunos de los identificadores no existen. Esto funciona en el
user.comments.where(id: avoided_ids_array)
También para excluir ID
Comment.where.not(id: [2, 3, 5])
Para evitar excepciones que maten su aplicación, debe detectar esas excepciones y tratarlas de la manera que desee, definiendo el comportamiento de su aplicación en aquellas situaciones en las que no se encuentra la identificación.
begin
current_user.comments.find(ids)
rescue
#do something in case of exception found
end
Aquí está más información sobre excepciones en ruby.
También puede usarlo en named_scope si desea poner otras condiciones
por ejemplo incluye algún otro modelo:
named_scope 'get_by_ids', lambda {| ids | {: include = > [: comentarios],: condiciones = > [" comments.id IN (?) " ;, ids]}}