2014-04-09 11 views
49

Ho una pagina di presentazione per i miei utenti e ogni attributo dovrebbe essere visibile solo su quella pagina, se non è nullo e non è una stringa vuota. Sotto ho il mio controller ed è abbastanza fastidioso dover scrivere la stessa riga del codice @user.city != nil && @user.city != "" per ogni variabile. Non ho molta familiarità con la creazione dei miei metodi, ma posso in qualche modo creare un collegamento per fare qualcosa del genere: @city = check_attr(@user.city)? O c'è un modo migliore per abbreviare questa procedura?Controllare se non è nullo e non vuoto nel collegamento di Rails?

users_controller.rb

def show 
    @city = @user.city != nil && @user.city != "" 
    @state = @user.state != nil && @user.state != "" 
    @bio = @user.bio != nil && @user.bio != "" 
    @contact = @user.contact != nil && @user.contact != "" 
    @twitter = @user.twitter != nil && @user.twitter != "" 
    @mail = @user.mail != nil && @user.mail != "" 
end 

risposta

139

C'è un metodo che fa per voi:

def show 
    @city = @user.city.present? 
end 

Le present? test metodo per non- nil plus dispone di contenuti. Stringhe vuote, stringhe costituite da spazi o tabulazioni, non sono considerate presenti.

Dal momento che questo modello è così comune c'è anche una scorciatoia in ActiveRecord:

def show 
    @city = @user.city? 
end 

Questo è più o meno equivalente.

Come nota, il test rispetto allo nil è quasi sempre ridondante. Ci sono solo due valori logicamente falsi in Ruby: nil e false. A meno che non è possibile per una variabile di essere letterale false, questo sarebbe sufficiente:

if (variable) 
    # ... 
end 

Questo è preferibile alla solita if (!variable.nil?) o if (variable != nil) roba che si presenta di tanto in tanto. Ruby tende a proteggere un tipo di espressione più riduzionista.

Uno dei motivi che ci si vuole confrontare vs nil è se si dispone di una variabile di tre stati che può essere true, false o nil ed è necessario distinguere tra le ultime due stati.

+6

Nota, a partire da Ruby 2.3.0 puoi liberarti di molti assegni ridondanti e nulli usando l'operatore solitario, qualcosa come 'if @user && @ user.authenticated' può diventare semplicemente' if @ user & .authenticated' –

8

È possibile utilizzare .present? che viene fornito con ActiveSupport.

@city = @user.city.present? 
# etc ... 

Si potrebbe anche scrivere in questo modo

def show 
    %w(city state bio contact twitter mail).each do |attr| 
    instance_variable_set "@#{attr}", @user[attr].present? 
    end 
end 

Vale la pena notare che, se si desidera verificare se qualcosa è vuoto, è possibile utilizzare .blank? (questo è l'opposto di .present?)

Inoltre, non utilizzare foo == nil. Utilizzare invece foo.nil?.

+0

puoi spiegare come funziona la prima linea ..? –

+0

@Mayank, l'OP sta impostando una variabile di istanza sul valore 'true' /' false'. 'reciever.present?' restituirà true se 'receiver' è un valore non vuoto. Si prega di consultare i documenti che ho collegato per ulteriori spiegazioni. – naomik

+0

grazie ho capito, ma non sono in grado di capire come instance_variable_set "@ # {attr}", @user [attr] .present? funzionerà..? –

Problemi correlati