Order by ... po wyszukaniu

Temat nie brzmi przejrzyscie, ale jak zwykle problem przedstawie na przykladzie.

Mam ksiazeczki, ktore sa powiazane ze stronami.

[code]#kontroler
@book = Book.find(params[:id])

#widok
<% for page in @book.pages%>
<%= page.name%>
<% end %>[/code]
W widoku wyswietlam wszystkie strony. Railsy je sortuja od najstarszej do najwnoszej. Ale chcialbym w kolejnosci odwrotnej. Najprosciej wyszukac wedlug stron, a nie wedlug ksiazek i tam dac order_by. Ale nie o takie rozwiazanie mi chodzi. Chcialbym posortowac @book.pages na zasadzie:

#widok <% for page in @book.pages.order_by("created_at ASC")%> <%= page.name%> <% end %>
Tyle, ze oczywiscie railsy tego nie łykają. Jest jakas dogodna metoda na to?

Dwie możliwości

  1. możesz sortować w całości po stronie klienta – wtedy otwierasz Ruby’ową dokumentację Array#sort z podaniem bloku i sortujesz po atrybucie jakim chcesz; wada – wydajność, nieeleganckie (od tego jest baza!)
  2. class Book
    has_many :pages, :order => “created_at ASC”

A może coś takiego zadziała?

# kontoller @books = Book.find(params[:id], :include => :pages, order_by => 'pages.created_at ASC')

:include przy relacji has_many? Prośba…

jak chcesz tylko odwrocic to jest moze nie najwydajniejszy ale sposob

for page in @book.pages.reverse

to trzeba dodac magiczne reverse

Zły, zły pomysł – baza SQL bez podania ORDER BY zwraca wyniki w niesprecyzowanej kolejności – konkretnie w kolejności dla siebie “najwygodniejszej”, co przy samym dodawaniu rekordów oznacza faktycznie kolejność chronologiczną ich dodawania. Ale już edycja (UPDATE) dowolnego rekordu spowoduje jego pojawienie się na nieokreślonym miejscu, z reguły na jednym z końców listy.

no no wiadomo, to byla tylko uwaga ze takie cos jest ze jak masz juz jakas kolejnosc sortowania ustalona i wykorzystujesz to w kilku miejscach, a w jednym chcesz w odwrotnej kolejnosci, to jest takie cos :stuck_out_tongue:

Trochę odbiegne od tematu, ale Tomash czemu stosowanie :include przy relacji has_many jest złe?

Nie jest złe, nie doczytałem dokumentacji, mój błąd (wydawało mi się że zachowa się jak podselecty, tj. zwróci wiele kopii tego samego wiersza tylko z innym doasocjowanym). Nieważne :slight_smile:

Zawsze można sobie również w modelu zdefiniować:

def order_by(order_type) self.find(:all, :order => order_type) end
albo wręcz named_scope order_by to będzie jeszcze czyściej… ale oczywiście include jest wydajniejsze itd… :wink:

Weź się wyśpij po tym urlopie, jak jutro zalogujesz i przeczytasz swojego posta to się złapiesz za głowę :smiley:
(są w nim błędy od koncepcyjno-projektowych po czysto programistyczne :stuck_out_tongue: )

Omg - faktycznie :stuck_out_tongue_winking_eye: Przyjechałem w środku nocy po 8h jazdy i się zabrałem za “coś pożytecznego” to widać skutki :stuck_out_tongue_winking_eye: Gorzej że w innym temacie zrobiłem plugin do SWF Web by Google i teraz nie mam nawet czasu sprawdzać jak bardzo powalony tam jest kod(bo to pisałem jeszcze o 1.30 a tamto o 4 nad ranem :stuck_out_tongue_winking_eye: )