2008-10-18 29 views
9

Korzystam z prostego wyszukiwania wszystkich stron i stronicowania z upartym, ale chciałbym również, aby zapytanie zostało posortowane przez użytkownika. Pierwsze rozwiązanie, które przyszło mi do głowy po prostu użyć params [: sortowanie]Szyny: Sortowanie zapytania według parametrów?

http://localhost:3000/posts/?sort=created_at+DESC 

@posts = Post.paginate :page => params[:page], :order => params[:sort] 

ale problem z jego podejścia jest to, że zapytanie jest zalegających sortowania przez ID i chcę go mieć created_at.

Czy jest to bezpieczne podejście do sortowania i czy istnieje sposób na domyślne utworzenie_at?

Odpowiedz

15

użyję nazwanego zakresu dostarczania kolejność domyślna (dostępna od Rails 2.1).

Można by dodać zakres w modelu post:

named_scope :ordered, lambda {|*args| {:order => (args.first || 'created_at DESC')} } 

Następnie można wywołać:

@posts = Post.ordered.paginate :page => params[:page] 

Powyższy przykład użyje domyślnej kolejności od named_scope (created_at DESC), ale możesz również podać inny:

@posts = Post.ordered('title ASC').paginate :page => params[:page] 

Możesz użyć t czapka z sugestią Romulo za:

sort_params = { "by_date" => "created_at", "by_name" => "name" } 
@posts = Post.ordered(sort_params[params[:sort]]).paginate :page => params[:page] 

Jeśli params[:sort] nie znajduje się w sort_params i zwraca nil następnie named_scope spadnie z powrotem do korzystania z domyślnej kolejności.

Railscasts ma kilka świetnych informacji na named_scopes.

2

Generalnie, sposób dostarczania wartości domyślnych dla Hash i Hash przedmiotów podobnych jest użycie fetch:

params.fetch(:sort){ :created_at } 

Wiele osób po prostu użyć || choć:

params[:sort] || :created_at 

Wolę fetch sam jako bardziej wyraźny, plus nie łamie się, gdy false jest uzasadniona wartość.

1

Ruby idiom ustawienie domyślne to:

@posts = Post.paginate :page => params[:page], :order => params[:sort] || "created_at" 

ale podejście nie jest bezpieczny. Metoda paginacji nie będzie zawracać sobie głowy parametrem, takim jak "created_at; DROP DATABASE mydatabase;". Zamiast tego można użyć słownika prawidłowych parametrów sort (niesprawdzone):

sort_params = { "by_date" => "created_at", "by_name" => "name" } 

@posts = Post.paginate :page => params[:page], :order => sort_params[params[:sort] || "by_date"] 

Tak, że URI staje:

http://localhost:3000/posts/?sort=by_date 
1

Wolę ten idiom:

@posts = Post.paginate :page=>page, :order=>order 
... 

def page 
    params[:page] || 1 
end 

def order 
    params[:order] || 'created_at ASC' 
end 
Powiązane problemy