Расширенный поиск с Rails - проблема с SQl-запросом Active Record - PullRequest
0 голосов
/ 27 мая 2018

Я построил функцию поиска поверх моего приложения rails, где я могу искать и фильтровать по имени и полу пользователя.Поиск работает правильно, единственное, что он не работает точно!

Например, если я ищу пользователей мужского пола, результаты поиска также получат меня пользователей женского пола.И я думаю, это потому, что я использую запрос ActiveRecord, в котором я сравниваю гендерный столбец таблицы пользователей с вставляемыми параметрами, а также потому, что слова «женский» и «мужской» - это два очень похожих слова, результаты которых связаны с двумяатрибутов.Этот запрос ActiveRecord, который я использовал, и он работает (хотя и не совсем точно):

"gender LIKE ? ", "%#{params[:gender]}%"

Поэтому я использовал другой запрос ActiveRecord:

"gender: %#{params[:gender]}%"

Второй запрос, к сожалению, все ломает.Я получаю эту ошибку в моем терминале:

SQLite3::SQLException: unrecognized token: ":": SELECT "users".* FROM "users" WHERE (gender: %Male%))

Предполагается, что эти запросы ActiveRecord принадлежат search_controller моей модели 'поиска'.Это мой контроллер:

  def index
    if params[:username] || params[:gender].present?
        @search = User.where('true').paginate(page: params[:page], per_page: 10)
        @search = User.where("name LIKE ? ", "%#{params[:username]}%") unless params[:username].blank?
        @search = User.where("gender LIKE ? ", "%#{params[:gender]}%") unless params[:gender].blank?
    else
        @search = User.all.paginate(page: params[:page], per_page: 10)
    end
  end

  def create
     @search = Search.create(username: params[:username], gender: params[:gender])
     redirect to @search
  end

  private

  def search_params
    params.require(:search).permit(:users, :gender)
  end

Это мой индекс моей поисковой модели, где я итерирую то, что ищем (@search) и отображаю в результатах поиска:

<h1> Your Search Results </h1>

<% if @search.nil? %>
  <p> No Results Found </p>


<% else %>

<ul class="users">
  <% @search.each do |user| %>
    <%= user.name %>
    <%= user.gender %>
  <% end %>

</ul>

<% end %>

<p><%= link_to 'All Users',  users_path %></p>

Это небольшое видео, где я могу объяснить, что я хочу сделать: https://drive.google.com/file/d/1G5FYytvmdI6iKjmwlH16NeftGwsEnLQU/view?usp=sharing

Ответы [ 2 ]

0 голосов
/ 27 мая 2018

Два вопроса: 1) точно соответствовать параметру, который вы можете сделать

@search = User.where(gender: params[:gender]) unless params[:gender].blank?

Остальное, что вы оставили, - это базовое условие LIKE, и если вы хотите сделать это с помощью LIKE, это правильный синтаксис

@search = User.where("gender LIKE ? ", "#{params[:gender]}") unless params[:gender].blank?

2) вы перезаписываете переменную @search, поэтому, если у вас есть оба параметра, ваш запрос параметра имени никогда не останется.Попробуйте это в конце

@search = User.all
@search = @search.where("name LIKE ? ", "%#{params[:username]}%") unless params[:username].blank?    
@search = @search.where("gender LIKE ? ", "%#{params[:gender]}%") unless params[:gender].blank?
0 голосов
/ 27 мая 2018

Использование LIKE ? делает ваш код уязвимым для SQL-инъекций , поэтому я определенно рекомендую вам изменить ваш подход.

Я думаю, что вы решите проблему, используя что-то вроде

User.where("name = ? AND gender = ?", params[:username], params[:gender])

Также принимайте Руководство по запросам на активную запись в качестве ориентира при каждом использовании запросов.Там вы найдете много полезного.

...