2010-05-01 13 views
12

He estado trabajando con Rails por un tiempo y una cosa que constantemente hago es verificar si algún atributo u objeto es nulo en mi código de vista antes de mostrarlo . Estoy empezando a preguntarme si esta es siempre la mejor idea.Comprobación de nil en vista en Ruby on Rails

Mi razonamiento hasta ahora ha sido que, dado que mi (s) aplicación (es) dependen de la entrada del usuario, pueden ocurrir cosas inesperadas. Si he aprendido una cosa de la programación en general, es que los usuarios que ingresan cosas en las que el programador no pensó es una de las mayores fuentes de errores en tiempo de ejecución. Al buscar valores nulos, espero eludir eso y permitir que mis puntos de vista manejen el problema con elegancia.

Aunque normalmente, por diversos motivos, tengo comprobaciones de valores nulos o inválidos similares en mi modelo o código de controlador. No lo llamaría duplicación de código en el sentido más estricto, pero simplemente no parece muy SECO. Si ya he comprobado que no hay objetos en mi controlador, ¿está bien si mi vista simplemente supone que el objeto realmente no es nulo? Para los atributos que pueden ser nulos que se muestran, tiene sentido para mí comprobarlo todo el tiempo, pero para los objetos en sí no estoy seguro de cuál es la mejor práctica.

Aquí está un ejemplo simplificado, pero es típico de lo que estoy hablando:

código del controlador

def show 
    @item = Item.find_by_id(params[:id]) 

    @folders = Folder.find(:all, :order => 'display_order') 

    if @item == nil or @item.folder == nil 
     redirect_to(root_url) and return 
    end 
end 

código de la vista

<% if @item != nil %> 
    display the item's attributes here 

    <% if @item.folder != nil %> 
     <%= link_to @item.folder.name, folder_path(@item.folder) %> 
    <% end %> 
<% else %> 
    Oops! Looks like something went horribly wrong! 
<% end %> 

¿Es esta una buena idea o es sólo ¿tonto?

Respuesta

6

Su ejemplo de código rehecho:

código del controlador. (Supongo que esto es ItemsController)

def show 
    # This will fail with 404 if item is not found 
    # You can config rails to pretty much render anything on Error 404 
    @item = Item.find(params[:id]) 

    # doesn't seem to be used in the view 
    # @folders = Folder.find(:all, :order => 'display_order') 


    # this is not needed anymore, or should be in the Error 404 handler 
    #if @item == nil or @item.folder == nil 
    # redirect_to(root_url) and return 
    #end 
end 

código de la vista, ya que el controlador se aseguró de que tenemos @item

#display the item's attributes here 

<%= item_folder_link(@item) %> 

código ayudante:

# display link if the item has a folder 
def item_folder_link(item) 
    # I assume folder.name should be a non-blank string 
    # You should properly validate this in folder model 
    link_to(item.folder.name, folder_path(item.folder)) if item.folder 
end 

De todos modos, trato de mantener a la vista muy muy simple. Por lo general, si veo bucles y condicionales en las vistas, trato de refactorizarlos en ayudantes.

5

No se debe utilizar yuu

<% if @item.nil? %> 

por ejemplo

@item1=nil 
if @item1.nil? ### true 
@item2 = "" 
if @item2.nil? ### false 
@item3 = [] 
if @item3.nil? ### false 
@item4 = {} 
if @item4.nil? ### false 

Para comprobar Un objeto está en blanco si es falso, vacío, o una cadena de espacios en blanco.

uso

<% if @item.blank? %> 

ref: - this

por ejemplo

@item1=nil 
if @item1.blank? #### true 
@item2 = "" 
if @item2.blank? #### true 
@item3 = [] 
if @item3.blank? #### true 
@item4 = {} 
if @item4.blank? #### true 
0

Su controlador es responsable de decidir qué va a ser prestados vista. Si puede verificar que su controlador nunca representará esta vista en particular sin un elemento o carpeta item_folder, entonces no necesita verificar valores nulos.

Por puedo verificar Quiero decir que tiene pruebas/especificaciones que verifican qué vista se representa para elementos nulos y item_folders.

0

Personalmente, creo que si está comprobando nulo en sus vistas (y creo que dado que la vista es la capa de presentación sin conexión, debe verificarse en ese nivel), no quiere verificarlo en el controlador.(Pero esto no se aplicará a todos los lugares)

le recomiendo que para crear un método para comprobar nula (para que sea poco seco) y pasar su objeto y comprobar si es nula o no

algo como

def is_nil (objeto) objeto.nil? ? '': Objeto final

y añadirlo en el controlador de aplicación y que sea un ayudante (de modo que se puede usar en ambos controladores y vistas)

(helper_method: is_nil - añadir esta línea a su solicitud controlador)

y ahora puede pasar el objeto que desea verificar si es nulo o no.

aplausos, sameera

2

No olvide .try, que se agregó en Rails 2.3. Esto significa que se puede llamar algo como lo siguiente:

@object.try(:name) 

Y si @object es nulo, se devolverá nada. Esta es quizás la solución integrada para la idea de sameera207.

Lo ideal es que no envíe objetos nulos a la vista, sin embargo, no siempre es posible evitarlos.