2009-06-27 6 views

Odpowiedz

7

Osobiście używam or Operator/słowo kluczowe:

(financial_document.assets or []).length 

czy inaczej, .length nazywa na tablicy, co daje 0 jeśli nil.

7

Mniej powtarzalnym sposobem radzenia sobie z tym jest upewnienie się, że plik financial_document.assets jest zawsze obiektem niezerowym, poprzez umieszczenie w nim odpowiedniej wartości sentinel (np. Pustej kolekcji lub specjalnego obiektu, który ma zdegenerowane zachowanie).

Zobacz The Null Object Pattern.

0

To jest Ruby, można dodać metodę długości do NilClass i go zawsze zwraca 0.

0

można zrobić to nieco krócej:

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

beca używaj

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

ale ogólnie rzecz biorąc, IMHO jest nie mniej powtarzalny sposób, tylko różne obejścia. (I to jest jedna z rzeczy, których nie lubię w Ruby.) Możesz upewnić się, że obiekty nie są puste (jak sugerują to inni ludzie) - ale nie możesz tego zrobić wszędzie. Możesz ominąć kod sprawdzający zero w metodach pomocniczych lub blokach ratowania początkowego.

Na przykład, zamiast dodawania metody długości do zera obiektu (co jest IMHO brudny Hack), bym napisał metody pomocnika - jest "długość getter":

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

Przypadek 1:

financial_document i assets mają wiele relacji. W takim przypadku financial_document.assets zawsze zwraca tablicę. Tak więc financial_document.assets.size dałoby 0, jeśli nie znaleziono pasującego wpisu podrzędnego, a rozmiar w przeciwnym razie.

Przypadek 2:

assets jest tylko metoda/atrybut financial_document. Następnie należy użyć tablicy return metody assets, aby zawsze można było wywoływać. Rozmiar na nim. Tak jak wskazał Joel.

3

W takim przypadku używam andand GEM:

financial_document.assets.andand.length || 0 
0

coś w modelu, który zwraca 0 lub długość. To powstrzymuje cię przed koniecznością zrobienia zwycięskiej rzeczy w twoim widoku. Takie rzeczy można zwykle zrobić w modelu.

class FinancialDocument 

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

sposób bardziej ogólny, aby rozwiązać tę klasę problemów jest to, aby dodać metodę próbować obiektu:

## 
    # @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 

wierzę Ruby 1.9 ma już metodę przymierzyć Object.

Następnie osiągnąłby pożądany wynik. Dzieje się tak, ponieważ nil.to_i zwraca 0

+0

próba została przeniesiona w Ruby Rails 1.8 do 2.3 - patrz http://railscasts.com/episodes/152-rails-2-3-extras –

1

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

try to metoda, która wywoła metodę obiektu, jeśli jej liczba zerowa w przeciwnym razie po prostu zwróci zero. I spróbuj na zero metod zawsze zwróci zero zamiast rzucać wyjątek.

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

ten sposób Ruby to zrobić!

+0

Sposób szynach, nie tak Ruby. – Jerph

1

Możesz to zrobić bez dodatkowych klejnotów. Używam ||, andand, try, ale poniższe wygląda łatwiej. Myślę, że jest to rubinowy sposób potwierdzania wzoru pustego obiektu Dave'a.

financial_document.assets.to_a.length 
Powiązane problemy