Jak sobie radzicie z find

Witam

Jestem początkującą osobą w Rails i w Ruby więc proszę o wyrozumiałość :stuck_out_tongue:

Jak sobie radzicie z tym, że metoda find z AR zwraca obiekt albo tablicę. Wpisujecie warunek do metody find i spodziewacie się tablicy, więc widok jest przygotowany na tablicę z <% for o in tab %> a tutaj kaplica bo find zwrócił jeden obiekt. Czy za każdym razem zanim coś zrobię mam sprawdzić do jakiej klasy należy mój wynik, czy jest może jakiś inteligenty sposób.

Dzięki

Model.find(666) # id = 666
Model.find(:first, :conditions => […]) # pierwszy obiekt spełniający wymogi wyszukiwania (mozesz uzyc :last)

zwróci jeden obiekt klasy Model.

Model.find(:all, :conditions => […])

zwróci tablicę, nawet jak będzie tam jeden obiekt.

Tak, zawsze robimy for, gdy tablica jest jednoelementowa pętla przejdzie tylko raz.

Dla pewności możesz też dopisać warunek czy w ogóle taka zmienna istnieje

for item in @twoja_tablica ... end if @twoja tablica

[quote=bober0]for item in @twoja_tablica ... end if @twoja tablica
[/quote]
Drobna sugestia: odradzam stosowania modyfikatorów if/unless/… w przypadku wielolinijkowych bloków kodu. Nie wygląda to najładniej i z całą pewnością nie zwiększa czytelności kodu. Podobnie w przypadku łańcuchowych wywołań, takich jak:

a = ["1", "2", "3"].map do |str| str.to_i end.sum

Nie rozumiem za bardzo problemu. Owszem, metoda AR#find zwraca tablicę lub 1 obiekt, ale jest to kompletnie deterministyczne zachowanie, więc obsłużenie tego nie powinno stanowić żadnego problemu.

Dlaczego tak sądzisz?
W widokach to dla mnie bardzo wygodne rozwiązanie.
W przykładzie który podałem if/unless jest tylko serwisowy. Ma za zadanie przewidzenie braku zmiennej.
Pętla się nie wykonuje gdy zmienna jest pusta lub nie jest zainicjalizowana.

Dodanie ifa powyżej pętli jest tylko stratą 2 lini.

if @twoja_tab for item in @twoja_tab .. end end
5 lini

for item in @twoja_tab .. end if @twoja_tab
tylko 3 linie

Z nudów wymyśliłem “ciekawy” hack z &&:

[code=ruby]@arr = [1, 2, 3]

@arr && for item in @arr
puts item
end

@arr && @arr.each do |item|
puts item
end[/code]
Można także użyć []=

(@arr ||= []).each do |item| puts item end
Chociaż akurat w widoku to powinno się mieć zawsze ustawioną zmienną.

A nie łatwiej:

[quote]@arr.to_a.each do |a|
#…
end[/quote]
nil.to_a == [] :slight_smile: