Verificando inexistente em Ruby on Rails

Eu tenho trabalhado com Rails por um tempo agora e uma coisa que eu me vejo constantemente fazendo é verificar se algum atributo ou object é nulo no meu código de visão antes de mostrá-lo. Estou começando a me perguntar se essa é sempre a melhor ideia.

Meu raciocínio até agora tem sido que, desde que meus aplicativos dependam da input do usuário, coisas inesperadas podem ocorrer. Se aprendi uma coisa com programação em geral, é que os usuários que inserem coisas que o programador não pensou são uma das maiores fonts de erros em tempo de execução. Ao verificar valores nulos, espero evitar isso e ter meus pontos de vista graciosamente manipulando o problema.

O problema é que, em geral, por vários motivos, tenho verificações de valor nulo ou inválido semelhantes no modelo ou no código do controlador. Eu não chamaria isso de duplicação de código no sentido mais estrito, mas simplesmente não parece muito seco. Se eu já tiver verificado objects nulos no meu controlador, tudo bem se a minha visão apenas assumir que o object realmente não é nulo? Para atributos que podem ser nulos que são exibidos, faz sentido verificar todas as vezes, mas, para os objects em si, não sei qual é a melhor prática.

Aqui está um exemplo simplificado, mas típico do que estou falando:

código do 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 

ver código

  display the item's attributes here     Oops! Looks like something went horribly wrong!  

Isto é uma boa ideia ou é apenas uma tolice?

Seu código de exemplo foi refeito:

código do controlador. (Eu suponho que isso é 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 

Ver código, desde que o controlador certificou-se de que temos @ item

 #display the item's attributes here <%= item_folder_link(@item) %> 

código auxiliar:

 # 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 qualquer forma, tento manter a visão muito simples. Geralmente, se vejo loops e condicionais em visualizações, tento refatorá-los em ajudantes.

Não você deveria usar

 <% if @item.nil? %> 

por exemplo

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

Para verificar Um object está em branco se for falso, vazio ou uma cadeia de espaço em branco.

usar

 <% if @item.blank? %> 

ref: – isto

por exemplo

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

Não esqueça o .try, que foi adicionado no Rails 2.3. Isso significa que você pode chamar algo como o seguinte:

 @object.try(:name) 

E se @object for nulo, nada será retornado. Esta é talvez a solução incorporada para a ideia do sameera207.

Idealmente, você não deveria estar enviando objects nulos para a visualização – no entanto, nem sempre é possível evitar.

Eu pessoalmente acho que se você está verificando nil em seus pontos de vista (e eu acho que desde que a visão é a última camada de apresentação nil deve ser verificada nesse nível), você não quer verificar no controlador. (mas isso não se aplica a todos os lugares)

Eu recomendo que você crie um método para verificar nil (para torná-lo pouco seco) e passar seu object e verificar se é nulo ou não

algo como:

 def is_nil(object) object.nil? ? '':object end 

e adicioná-lo no controlador de aplicativo e torná-lo um ajudante (para que você possa usá-lo em ambos os controladores e visualizações)

( helper_method :is_nil – adiciona esta linha ao seu controlador de aplicativo)

e agora você pode passar o object que você quer verificar se é nulo ou não.

Felicidades,

sameera

Seu controlador é responsável por decidir qual visualização será renderizada. Se você puder verificar se o seu controlador nunca renderizará essa visualização específica sem um item ou uma pasta de item, você não precisará verificar valores nulos.

Por verificar, quero dizer que você tem testes / especificações que verificam qual visualização é renderizada para itens nulos e pastas_do_parte.