Hej,
Właśnie zacząłem pisać moją pierwszą aplikację w railsach, w sumie to, to co chciałem działa, ale mam jakieś dziwne wrażenie, że można to wszystko zrobić dużo ładniej i przejrzyściej.
O co chodzi.
Mam dwa zestawy linków:
Rodzaj wpisów: Kategoria1, Kategoria2, Kategoria3 - odpowiednio ?type=0,1,2 i brak ?type - wszystkie
Sortowanie: Popularne, Komentowane, Najlepsze - odpowiednio ?order nil,1,2,
link Next z willpaginate
Powinno to działać standardowo, czyli klikam Kategoria1 i ten ?type=0 jest cały czas przy linkach do sortowania, tak samo z Kategoria2 i 3.
Będę wdzięczny za wszelkie konstruktywne zjebki (na razie to pierwszy kontroler i pierwsza akcja + mega prosty model bez żadnych walidacji:)
Tutaj, wydaje mi się, że to moje generowanie t, żeby później zrobić where("#{t}") jest jakoś na około, pewnie da się dużo prościej takie zapytanie sklecić.
class EntryController < ApplicationController
def index
#params[:order] - brak - popularne (domyslne), 1 - komentowane, 2 - najlepsze
#params[:type] - 0 kategoria1, 1 - kategoria2, 2 - kategoria3
#buduje t = wygenerowany fragment pod where 'entry_type = ...'
!params[:type]? t = "1==1" : t = "entry_type="+params[:type]
if !params.has_key?(:order)
@entries=Entry.where("#{t}").order("rank DESC").page(params[:page]).per_page(20)
elsif params[:order] == "1"
@entries=Entry.where("#{t}").order("comments_count DESC").page(params[:page]).per_page(20)
elsif params[:order] == "2"
@entries=Entry.where("#{t}").order("points_count DESC").page(params[:page]).per_page(20)
end
end
end
A we view mam taki kod (dodaje class=“active” dla aktualnie wybranego linku i zamienia go w zwykly test) - jakoś mi ten html_safe śmierdzi, ale nie chciałem rozbijać tak krótkiego kodu na jakieś większe if elsy.
t = "entry_type=" + params[:type] unless params[:type].empty?
Jak nie będzie, to dostaniesz nila, i później:
o = case params[:order]
when "1" then "comments_count"
when "2" then "points_count"
else "rank"
end
o += " DESC"
@entries = Entry.where(t).order(o).page(params[:page]).per_page(20) unless params[:order].empty?
Rzecz w tym, że to i tak niepełen refactor - ja bym wyjął jeszcze to mapowanie ordera poza metodę kontrolera.
ps. tam zamiast def search_type i search_order powinno być self.search_type i self.search_order, nie kapuję tylko dlaczego - będę wdzięczny za wytłumaczenie, ewentualnie jakiś link.
ahh, słusznie, literówka. #search to metoda klasowa (wywoływana na klasie a nie instancji klasy), więc może wołać tylko inne metody klasowe, #search_type i #search_order były tutaj metodami instancji.
[code=ruby] def search_order(order)
return ‘comments_count DESC’ if order == ‘1’
return ‘points_count DESC’ if order == ‘2’
'rank DESC'
end[/code]
Polecam w takich przypadkach zamiast ifów zrobić np. hash
[code=ruby]search_order[order]
def search_order
{ ‘1’ => ‘comments_count DESC’, ‘2’ => ‘points_count DESC’, nil => ‘rank DESC’ }
end[/code]
Jak ‘rank DESC’ ma być użyty dla każdego innego przypadku, a nie tylko dla nil to możesz użyć domyślnej wartości hasha.
def search_order(order)
SEARCH_ORDER[order] || ‘rank DESC’
end[/code]
No dobra, a na serio, co to za odgrzewanie tematów? Staszkowi ukradli konto i się kolejny SEO spammer szykuje?