2013-05-22 10 views
58

Nella mia app l'utente può creare un'attività. Quando si innescano l'azione index nel mio BusinessesController voglio verificare se un business è legato alla current_user.id:Verificare se esiste un record dal controller in Rails

  • Se sì: visualizzare il business.
  • In caso di no: reindirizzamento all'azione new.

stavo cercando di usare questo:

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

ma restituisce sempre vero anche quando l'azienda non esiste ...

Come posso verificare se esiste un record in il mio database?

+1

Utilizzare 'where' restituirà un array vuoto se non ci sono record. E '[]' non è uguale a 'nil' –

+0

Cosa ne pensi di un' meno Business.find_by_user_id (current_user.id) '? – Hengjie

+0

possibile duplicato di [Verificare se ActiveRecord find restituisce un risultato] (http://stackoverflow.com/questions/2866473/checking-if-activerecord-find-returns-a-result) –

risposta

172

Perché il codice non funziona?

Procedimento where restituisce un ActiveRecord :: Relation oggetto (agisce come un array che contiene i risultati della where), può essere vuoto ma non sarà mai 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 

come testare se esiste almeno un record?

Opzione 1: Uso.exists?

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

Opzione 2: Utilizzo.present? (o .blank?, il contrario di .present?)

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

Opzione 3: assegnazione variabile nel if

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

Questa opzione può essere considerato un codice odore da parte di alcuni Linters (Rubocop per esempio).

opzione 3b: assegnazione variabile

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

È anche possibile utilizzare .find_by_user_id(current_user.id) invece di .where(...).first


opzione migliore:

  • Se non lo fai utilizzare l'oggetto Business (s): Opzione 1
  • Se è necessario utilizzare l'oggetto Business (s): Opzione 3
+0

Questo non sembra funzionare.Continua a superare quel test e caricando l'indice html come con il test == nil (quindi sto ricevendo un errore: metodo 'nome 'non definito per nil: NilClass). –

+0

Provare prima di chiamare il presente – MrYoshiji

+0

Ho lo stesso problema –

1

ActiveRecord # dove restituirà un oggetto ActiveRecord :: Relation (che non sarà mai nullo). Prova a usare .empty? sulla relazione per testare se restituirà qualsiasi record.

1

Quando si chiama Business.where(:user_id => current_user.id) si otterrà un array. Questa matrice potrebbe non avere oggetti o uno o più oggetti, ma non sarà nulla. Quindi il controllo == nil non sarà mai vero.

si può provare il seguente:

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

Così si controlla il numero di elementi nella matrice e confrontarle con zero.

o si può provare:

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

questo restituirà uno o zero.

24

In questo caso mi piace usare il metodo exists? fornito da ActiveRecord:

Business.exists? user_id: current_user.id 
3

con 'esiste?':

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

con 'qualsiasi?':

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

Se si utilizza qualcosa con .dove, essere sicuri di evitare problemi con gli ambiti e l'uso migliore .unscoped

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

Meglio utilizzare Business.unscoped.where (: user_id => current_user.id) .pluck (: id) .any? per evitare il sovraccarico di relazioni per l'oggetto che stai controllando. – Juanin

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

vorrei farlo in questo modo, se avete bisogno di una variabile di istanza dell'oggetto con cui lavorare :

if @business = Business.where(:user_id => current_user.id).first 
    #Do stuff 
else 
    #Do stuff 
end 
Problemi correlati