Rails: сортировка запроса по параметрам? - PullRequest
9 голосов
/ 18 октября 2008

Я использую простой поиск всех и разбивку на страницы с помощью willpaginate, но я также хотел бы, чтобы запрос был отсортирован пользователем. Первое решение, которое пришло на ум, было просто использовать params [: sort]

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

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

Но проблема с его подходом заключается в том, что запрос по умолчанию сортируется по идентификатору, и я хочу, чтобы он был создан__.

Является ли это безопасным подходом к сортировке и есть ли способ по умолчанию для create_at?

Ответы [ 4 ]

15 голосов
/ 18 октября 2008

Я бы использовал именованную область для предоставления порядка по умолчанию (доступно с Rails 2.1).

Вы добавили бы область действия в вашу модель Post:

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

Тогда вы можете позвонить:

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

В приведенном выше примере будет использоваться порядок по умолчанию из named_scope (created_at DESC), но вы также можете указать другой:

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

Вы можете использовать это с предложением Ромуло:

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

Если params[:sort] не найден в sort_params и возвращает nil, тогда named_scope вернется к использованию порядка по умолчанию.

Railscasts содержит отличную информацию о named_scopes.

2 голосов
/ 18 октября 2008

Как правило, для предоставления значений по умолчанию для хеш-объектов и хеш-подобных объектов необходимо использовать fetch:

params.fetch(:sort){ :created_at }

Многие люди просто используют ||, хотя:

params[:sort] || :created_at

Я предпочитаю fetch как более явный, плюс он не прерывается, когда false является допустимым значением.

1 голос
/ 19 октября 2008

Я предпочитаю эту идиому:

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

def page
  params[:page] || 1
end

def order
  params[:order] || 'created_at ASC'
end
1 голос
/ 18 октября 2008

Идиома Ruby для установки по умолчанию будет:

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

Но этот подход небезопасен. Метод разбивки на страницы не будет беспокоить такой параметр, как "created_at; DROP DATABASE mydatabase;". Вместо этого вы можете использовать словарь допустимых параметров сортировки (непроверенный):

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

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

Так что URI становится:

http://localhost:3000/posts/?sort=by_date
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...