рельсы, как написать запрос с таблицей соединений и условиями - PullRequest
0 голосов
/ 09 января 2019

У меня есть две таблицы, Категория и Продукт

  create_table "categories", force: :cascade do |t|
    t.string "title", limit: 100, null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "products", force: :cascade do |t|
    t.string "title", limit: 150, null: false
    t.decimal "price", precision: 15, scale: 2, default: "0.0", null: false
    t.text "description"
    t.bigint "category_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "color"
    t.integer "user_id"
    t.json "attachments"
    t.index ["category_id"], name: "index_products_on_category_id"
  end

В моей форме поиска пользователь может ввести ключевое слово, которое может соответствовать:

  • название продукта
  • цвет продукта
  • описание товара
  • Цвет продукта

Также он должен найти по названию категории продукта.

В моем контроллере продукта у меня есть такой метод:

def filter_products
  return if params[:query].blank?
  @products = Product.joins(:category).where('lower(categories.title) LIKE ?', "%#{params[:query][:keyword]}%")
  @products = Product.where('lower(title) LIKE ?', "%#{params[:query][:keyword]}%")
      .or(Product.where('lower(description) LIKE ?', "%#{params[:query][:keyword]}%"))
      .or(Product.where('lower(color) LIKE ?', "%#{params[:query][:keyword]}%"))
end

Когда я ищу товар по его категории, он ничего не возвращает

Возвращает ожидаемое, если удалить эту строку:

 @products = Product.where('lower(title) LIKE ?', "%#{params[:query][:keyword]}%")
    .or(Product.where('lower(description) LIKE ?', "%#{params[:query][:keyword]}%"))
    .or(Product.where('lower(color) LIKE ?', "%#{params[:query][:keyword]}%"))

Поскольку невозможно использовать объединяет с или в запросе ...

Как мне изменить свой метод, чтобы он возвращался либо по названию категории продукта, либо по продукту (название, описание, цвет)?

1 Ответ

0 голосов
/ 09 января 2019

На основе вашего кода вторая строка запроса переопределяет переменную @products.

Даже если вы не переопределите переменную @products, Rails в этом случае поместит оператор «и» SQL между вашей первой и второй строкой запроса. Более понятный способ сделать это - написать необработанный SQL, в котором предложения объединяются с помощью оператора 'или'

Код будет

cols = ["`categories`.`title` LIKE :query","`products`.`title` LIKE :query", "`products`.`description` LIKE :query", "`products`.`position` LIKE :query"]

@products = Product.joins(:category).where(cols.join(" OR "), query: "%#{{params[:query][:keyword]}%")

, что намного понятнее и меньше кода.

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