2009-06-27 11 views

Respuesta

7

En lo personal, me gustaría utilizar el or operador/palabra clave:

(financial_document.assets or []).length 

De cualquier manera, .length se llama en una matriz, dando 0 si nil.

7

La manera menos repetitiva de tratar esto es asegurar que financial_document.assets sea siempre un objeto no nulo, organizando que contenga un valor centinela apropiado (por ejemplo, una colección vacía, o un objeto especial que tiene comportamiento degenerado).

Ver The Null Object Pattern.

0

Siendo este Ruby, se podría añadir un método de longitud para NilClass y tenerlo siempre devolverá 0.

0

puede que sea un poco más corto:

financial_document.assets ? financial_document.assets.length : '0' 

beca use

financial_document.assets == !financial_document.assets.nil? 

pero en general, en mi humilde opinión no hay una manera menos repetitiva, solo varias soluciones. (Y esta es una de las cosas que no me gustan tanto en Ruby.) Puedes asegurarte de que los objetos no son nulos (como otras personas sugieren aquí), pero no puedes hacer eso en todas partes. Puede envolver el código de comprobación cero en los métodos de ayuda o en los bloques de inicio y rescate.

Por ejemplo, en lugar de añadir método de longitud de objeto nulo (que en mi humilde opinión es un truco sucio), me escribió un método de ayuda - un "captador de longitud":

def fd_length(financial_document) 
    financial_document.assets ? financial_document.assets.length : '0' 
end 
3

Caso 1:

financial_document y assets tienen muchas relaciones. En este caso, financial_document.assets siempre devuelve una matriz. Por lo tanto, financial_document.assets.size le daría 0 si no se encuentra ninguna entrada secundaria y, de lo contrario, el tamaño.

Caso 2:

assets es sólo un método/atributo en financial_document. Luego tenga la matriz de devolución del método assets, para que siempre pueda llamar .size en ella. Al igual que Joel ha señalado.

3

En tal caso uso andand joya:

financial_document.assets.andand.length || 0 
0

Algo en el modelo que devuelve 0 o la longitud. Esto evita que tengas que hacer una cosa convaluada desde tu punto de vista. Cosas como esta normalmente se pueden hacer en el modelo.

class FinancialDocument 

    def assets_length 
    assets.length.blank? 0 : assets.length 
    end 
end 
3

Una forma más genérica para resolver esta clase de problemas es añadir un método de tratar de objeto:

## 
    # @user.name unless @user.nil? 
    # vs 
    # @user.try(:name) 
    # 
    def try(method, *args, &block) 
    return nil unless method 
    return nil if is_a?(NilClass) and [:id, 'id'].include?(method) 
    self.send(method, *args, &block) if respond_to?(method) 
    end 

Creo Ruby 1.9 ya cuenta con un método de prueba en objeto.

Entonces financial_document.assets.try(:length).to_i lograría el resultado deseado. Esto es porque nil.to_i devuelve 0

+0

intento fue portado en Ruby 1.8 para Rails 2.3 - ver http://railscasts.com/episodes/152-rails-2-3-extras –

1

financial_document.assets.try (: longitud) || 0

try es un método que invocará el método del objeto si no es nulo sino devuelve nil. Y pruebe nil métodos siempre devolverá nil en lugar de arrojar una excepción.

http://api.rubyonrails.org/classes/Object.html#method-i-try

Ésta es la manera de Ruby para hacer esto!

+0

La forma rieles, no la forma en Ruby. – Jerph

1

Puedes hacerlo sin gemas adicionales. He estado usando ||, andand, try, pero el siguiente parece más simple. Creo que es la forma de rubí para confirmar el patrón de objetos nulos de Dave.

financial_document.assets.to_a.length 
Cuestiones relacionadas