it-swarm.com.de

Überprüfen Sie, ob ein Datensatz vom Controller in Rails vorhanden ist

In meiner App kann ein Benutzer ein Unternehmen erstellen. Wenn sie die Aktion index in meinem BusinessesController auslösen, möchte ich überprüfen, ob ein Unternehmen mit dem current_user.id Zusammenhängt:

  • Wenn ja: Anzeige des Geschäfts.
  • Wenn nein: Weiterleiten an die Aktion new.

Ich habe versucht, dies zu verwenden:

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

Aber es ist immer wahr, auch wenn das Geschäft nicht existiert ...

Wie kann ich testen, ob ein Datensatz in meiner Datenbank vorhanden ist?

77
user470763

Warum funktioniert Ihr Code nicht?

Die where -Methode gibt ein ActiveRecord :: Relation -Objekt zurück (verhält sich wie ein Array, das die Ergebnisse des where enthält. ), kann leer sein, wird aber niemals nil sein.

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

Wie prüfe ich, ob mindestens ein Datensatz vorhanden ist?

Option 1: Verwenden von .exists?

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

Option 2: Verwenden von .present? (oder .blank? , das Gegenteil von .present?)

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

Option 3: Variablenzuordnung in der if-Anweisung

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

Diese Option kann von einigen Lintern (z. B. Rubocop) als Codegeruch angesehen werden.

Option 3b: Variablenzuordnung

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

Sie können auch .find_by_user_id(current_user.id) anstelle von .where(...).first verwenden.


Beste Option:

  • Wenn Sie die Business -Objekte nicht verwenden: Option 1
  • Wenn Sie die Business -Objekte verwenden müssen: Option 3
209
MrYoshiji

In diesem Fall verwende ich gerne das exists? Methode von ActiveRecord:

Business.exists? user_id: current_user.id
26
Hamed

mit 'existiert?':

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

mit jedem?':

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

Wenn Sie etwas mit .where verwenden, vermeiden Sie unbedingt Probleme mit dem Gültigkeitsbereich und verwenden Sie besser . Unscoped

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

ActiveRecord #, wobei ein ActiveRecord :: Relation-Objekt zurückgegeben wird (das niemals null sein wird). Versuchen Sie es mit .empty? auf die Beziehung zu testen, ob es Datensätze zurückgeben wird.

1
Puhlze

Wenn Sie Business.where(:user_id => current_user.id) aufrufen, erhalten Sie ein Array. Dieses Array enthält möglicherweise keine Objekte oder ein oder mehrere Objekte, ist jedoch nicht null. Somit wird die Prüfung == nil niemals wahr sein.

Sie können Folgendes versuchen:

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

Sie überprüfen also die Anzahl der Elemente im Array und vergleichen sie mit Null.

oder Sie können versuchen:

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

dies wird eins oder null zurückgeben.

1
marimaf

Ich würde es so machen, wenn Sie eine Instanzvariable des Objekts benötigen, um damit zu arbeiten:

if @business = Business.where(:user_id => current_user.id).first
  #Do stuff
else
  #Do stuff
end
0
user3633260
business = Business.where(:user_id => current_user.id).first
if business.nil?
# no business found
else
# business.ceo = "me"
end
0
Nino van Hooff