2011-03-22 16 views
8

Tengo el siguiente código de rubí muy feo en una aplicación de rieles que estoy trabajando:Ruby: Nils en una instrucción IF

if params.present? 
    if params[:search].present? 
    if params[:search][:tags_name_in].present? 
     ... 
    end 
    end 
end 

Todo lo que estoy tratando de hacer es si params [:] [búsqueda : tags_name_in] se ha definido, sino porque params, y params [:] de búsqueda, y params [:] [búsqueda: tags_name_in] podría ser nulo todo, si uso ...

if params[:search][:tags_name_in].present? 

... I obtener un error si no hay params o no hay parámetros de búsqueda.

Seguramente debe haber una mejor manera de hacer esto ... sugerencias?

+0

Una nota sobre qué respuesta Tomé: En mi aplicación de su no importa si esta condición devuelve 'nil' o' false', ni es importante que ': tags_name_in' no esté en blanco, solo necesito probar si': tags_name_in' se define sin generar un error. Entonces, para mi situación, me gusta el enfoque 'definido?' Dado por Will Ayd. Sin embargo, creo que el enfoque de Mike Lewis puede ser más útil para otros que pueden necesitar evitar pasar un valor nulo a su condición. Por lo tanto, mire ambas respuestas y decida si eso importa en su situación. – Andrew

Respuesta

10

si solo está tratando de ver si está definido ¿por qué no mantenerlo simple y usar el definido? ¿función?

if defined?(params[:search][:tags_name_in]) 
+0

este es bueno :) – fl00r

+2

Esto no es equivalente al código que originalmente le preguntó. 'defined?' devolverá true si se ha inicializado una variable, incluso si está configurada en 'nil'. 'present?' verifica usando 'blank?', por lo que 'nil' devolverá false. –

+0

seguro, pero la pregunta dice que solo está preguntando si se ha definido o no, lo que hará. –

6

Los parametros siempre se definirán, por lo que puede eliminarlos.

Para reducir la cantidad de código que puede hacer

if params[:search] && params[:search][:tags_name_in] 
    #code 
end 

Si params[:search] no está definido, la condición de cortocircuito y volver nil.

+0

He editado para indicar que devuelve 'nil', no' false'. –

+0

Ah, buena captura. Gracias. –

+1

Está asumiendo que este código está en un controlador de rieles. Dentro de alguna clase, los params pueden ser indefinidos o nulos. –

0

por lo general termino haciendo algo como esto:

if params.has_key?(:search) && params[:search].has_key?(:tags_name_in) 
... 

end 

Aunque si no te importa las pruebas contra Nils en su sentencia if también se puede hacer esto:

if params[:search] && params[:search][:tags_name_in] ... 

esto no será arrojar un error porque ruby ​​short-circuits el operador & &.

4

Puede usar andand para esto. Se ocupa de esta situación exacta:

if params[:search].andand[:tags_name_in].andand.present?

+0

Esta es una joya muy buena, ¡gracias por la propina! – Andrew

+0

+1 si solo todos usaran y en estos casos (aunque prefiero escribir el equivalente "ick" tal vez ") en lugar de condicionales y más condicionales (o el feo" intento ") – tokland

3

Jaja, si quieres ser terrible y monkeypatch nula:

class NilClass 
    def [](key) 
    nil 
    end 
end 

Yo recomendaría una cortocircuitado si como las otras respuestas sugieren, sin embargo.

+0

¿Por qué es malo? Me parece muy bien. –

4

usted tiene muchas opciones que devolverá el valor de params[:search][:tags_name_in] o nilparams[:search] si es nil.

Claro, pero muy largo:

params[:search] && params[:search][:tags_name_in] 

Usando try (de active_support):

params[:search].try(:[], :tags_name_in) 

Uso de rescate:

params[:search][:tags_name_in] rescue nil 

Usando fetch:

params.fetch(:search, {})[:tags_name_in] 

Tenga en cuenta que fetch en algún momento se puede utilizar para evitar la if por completo, especialmente si no hay nada que hacer cuando no se especifica el parámetro:

def deal_with_tags 
    MyModel.where :tags => params.fetch(:search){ return }[:tags_name_in] 
end 
+0

+1. Estaba a punto de publicar la solución 'try' y' fetch'. Dejé de usar 'rescate' en línea después de encontrar el costo del manejo de excepciones en Ruby. –

+0

El método fetch se ve muy útil, lo buscaré y ¡podré usarlo en varios lugares! – Andrew

+0

¡OP necesita tratar con params siendo nulo! Esta respuesta todavía arrojaría errores en ese caso. –

Cuestiones relacionadas