ruby on rails - validaciones - Compruebe si existe registro desde el controlador en Rails
formularios en ruby on rails (7)
En mi aplicación, un usuario puede crear un negocio. Cuando desencadenan la acción de index
en mi BusinessesController
, quiero verificar si un negocio está relacionado con el current_user.id
:
- En caso afirmativo: muestre el negocio.
- Si no, redirija a la
new
acción.
Intentaba 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?
ActiveRecord # donde devolverá un objeto ActiveRecord :: Relation (que nunca será nulo). Intenta usar .empty? en la relación para comprobar si devolverá algún registro.
Cuando llame a Business.where(:user_id => current_user.id)
obtendrá una matriz. Esta Matriz puede no tener objetos o uno o muchos objetos en ella, pero no será nula. Por lo tanto, el cheque == nil nunca será verdadero.
Puedes probar lo siguiente:
if Business.where(:user_id => current_user.id).count == 0
Entonces, verifica la cantidad 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 nada.
En este caso, me gusta usar el exists?
método provisto por ActiveRecord:
Business.exists? user_id: current_user.id
Lo haría de esta manera si necesitaras una variable de instancia del objeto para trabajar:
if @business = Business.where(:user_id => current_user.id).first
#Do stuff
else
#Do stuff
end
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 ámbitos y un mejor uso .unscoped
Business.unscoped.where(:user_id => current_user.id).any?
¿Por qué tu código no funciona?
El método where
devuelve un objeto ActiveRecord :: Relation (actúa como una matriz que contiene los resultados de where
), puede estar vacío pero nunca será 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: ¿ Utiliza .exists?
if Business.exists?(user_id: current_user.id)
# same as Business.where(user_id: current_user.id).exists?
# ...
else
# ...
end
Opción 2: ¿Cómo usar .present?
(o .blank?
lo opuesto a .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 variables en la sentencia if
if business = Business.where(:user_id => current_user.id).first
business.do_some_stuff
else
# do something else
end
Esta opción se puede considerar un olor de código por algunos linters (Rubocop, por ejemplo).
Opción 3b: asignación de variables
business = Business.where(user_id: current_user.id).first
if business
# ...
else
# ...
end
También puede usar .find_by_user_id(current_user.id)
lugar de .where(...).first
Mejor opción:
- Si no usa el objeto
Business
(s): Opción 1 - Si necesita usar el objeto
Business
(s): Opción 3
business = Business.where(:user_id => current_user.id).first
if business.nil?
# no business found
else
# business.ceo = "me"
end