2015-11-05 3 views
0

Пользователь хочет выполнить поиск по атрибуту и ​​/ или заказать результаты. Вот несколько примеров запросовЗапрос модели Rails с множеством необязательных параметров

/posts?order=DESC&title=cooking 
/posts?order=ASC 
/posts?title=cooking 

Как я могу условно связать такие параметры, чтобы сформировать запрос?

До сих пор у меня очень уродливый метод, который быстро станет трудно поддерживать.

def index 
    common = Hash.new 
    common["user_id"] = current_user.id 

    if params[:order] && params[:title] 

     @vacancies = Post.where(common) 
          .where("LOWER(title) LIKE ?", params[:title]) 
          .order("title #{params[:order]}") 

    elsif params[:order] && !params[:title] 

     @vacancies = Post.where(common) 
          .order("title #{params[:order]}") 

    elsif params[:title] && !params[:order] 

     @vacancies = Post.where(common) 
          .where("LOWER(title) LIKE ?", params[:title]) 
    end 
    end 

ответ

1

Помните, что методы запроса, как where и order предназначены для прикован. То, что вы хотите сделать, это начать с базовым запросом (например, Post.where(common), который вы используете во всех случаях), а затем условно цепь других методов:

def index 
    common = Hash.new 
    common["user_id"] = current_user.id 

    @vacancies = Post.where(common) 

    if params[:order] 
    @vacancies = @vacancies.order(title: params[:order].to_sym) 
    end 

    if params[:title] 
    @vacancies = @vacancies.where("LOWER(title) LIKE ?", params[:title]) 
    end 
end 

P.S. В вашем исходном коде был .order("title #{params[:order]}"). Это очень опасно, так как оно открывает вам атаки SQL-инъекций. Как правило, never использовать конкатенацию строк (#{...}) со значением, которое вы получаете от конечного пользователя, когда вы собираетесь передать результат в базу данных. Соответственно, я изменил его на .order(title: params[:order]). Rails будет использовать этот хеш для создания безопасного запроса, поэтому вам не придется беспокоиться об атаках с инъекциями.

Подробнее об атаках по SQL-инъекциям в Rails в официальном Ruby on Rails Security Guide.

+1

Отличный ответ. Одна маленькая вещь, пришлось преобразовать «порядок» в символ, чтобы заставить это работать: 'params [: order] .to_sym'. Только ошибка: asc и: desc были приняты указания. – frostbite

+0

Хороший улов. Я обновил свой ответ. –

Смежные вопросы