Verifique si existe un registro del controlador en Rails


91

En mi aplicación, un usuario puede crear una empresa. Cuando desencadenan la indexacción en mi BusinessesControllerquiero comprobar si un negocio está relacionado con current_user.id:

  • En caso afirmativo: muestre el negocio.
  • Si no: redirige a la newacción.

Estaba tratando de usar esto:

if Business.where(:user_id => current_user.id) == nil
  # no business found
end

Pero siempre vuelve verdadero incluso cuando el negocio no existe ...

¿Cómo puedo probar si existe un registro en mi base de datos?


1
El uso wheredevolverá una matriz vacía si no hay registros. Y []no es igualnil
mind.blank

¿Qué tal solo un unless Business.find_by_user_id(current_user.id)?
Hengjie

Respuestas:


231

¿Por qué tu código no funciona?

El wheremétodo devuelve un objeto ActiveRecord :: Relation (actúa como una matriz que contiene los resultados del where), puede estar vacío pero nunca lo estaránil .

Business.where(id: -1) 
 #=> returns an empty ActiveRecord::Relation ( similar to an array )
Business.where(id: -1).nil? # ( similar to == nil? )
 #=> returns false
Business.where(id: -1).empty? # test if the array is empty ( similar to .blank? )
 #=> returns true

¿Cómo probar si existe al menos un registro?

Opción 1: usar.exists?

if Business.exists?(user_id: current_user.id)
  # same as Business.where(user_id: current_user.id).exists?
  # ...
else
  # ...
end

Opción 2: Usar .present?(o .blank?lo contrario de .present?)

if Business.where(:user_id => current_user.id).present?
  # less efficiant than using .exists? (see generated SQL for .exists? vs .present?)
else
  # ...
end

Opción 3: Asignación de variable en la instrucción if

if business = Business.where(:user_id => current_user.id).first
  business.do_some_stuff
else
  # do something else
end

Esta opción puede ser considerada un olor a código por algunos linters (Rubocop por ejemplo).

Opción 3b: asignación de variable

business = Business.where(user_id: current_user.id).first
if business
  # ...
else
  # ...
end

También puede usar en .find_by_user_id(current_user.id)lugar de.where(...).first


Mejor opción:

  • Si no usa el Business(los) objeto (s): Opción 1
  • Si necesita usar el Businessobjeto (s): Opción 3

Eso no pareció funcionar. Sigue pasando esa prueba y cargando el índice html como con la prueba == nil (así que obtengo un error: método indefinido `nombre 'para nil: NilClass).

Pruebe primero antes de llamar al presente
MrYoshiji

Tengo el mismo problema

Oh, eso es mi culpa, estaba confundido, necesitas probar conblank?
MrYoshiji

¡Gracias que funcionó! No debería haber notado ese error. ¿Podría decirme por qué no funcionó la comprobación == nil?

29

En este caso, me gusta usar el exists?método proporcionado por ActiveRecord:

Business.exists? user_id: current_user.id

¿Existe? con O posible?
Imran Ahmad

5

con 'existe?':

Business.exists? user_id: current_user.id #=> 1 or nil

¿con cualquier?':

Business.where(:user_id => current_user.id).any? #=> true or false

Si usa algo con .where, asegúrese de evitar problemas con los visores y utilice mejor .

Business.unscoped.where(:user_id => current_user.id).any?

Es mejor usar Business.unscoped.where (: user_id => current_user.id) .pluck (: id) .any? para evitar una carga innecesaria de relaciones para el objeto que está comprobando.
Juanin

1

ActiveRecord # donde devolverá un objeto ActiveRecord :: Relation (que nunca será nulo). ¿Intenta usar .empty? en la relación para probar si devolverá algún registro.


1

Cuando llame Business.where(:user_id => current_user.id), obtendrá una matriz. Esta matriz puede no tener objetos o tener uno o muchos objetos, pero no será nula. Por tanto, la comprobación == nil nunca será verdadera.

Puedes probar lo siguiente:

if Business.where(:user_id => current_user.id).count == 0

Entonces, verifica el número de elementos en la matriz y los compara con cero.

o puedes probar:

if Business.find_by_user_id(current_user.id).nil?

esto devolverá uno o nulo.


1
business = Business.where(:user_id => current_user.id).first
if business.nil?
# no business found
else
# business.ceo = "me"
end

0

Lo haría de esta manera si necesitara una variable de instancia del objeto para trabajar:

if @business = Business.where(:user_id => current_user.id).first
  #Do stuff
else
  #Do stuff
end
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.