繁体   English   中英

如何使用很少的选项从连接表中选择数据记录?

[英]How to select data records from join table with few options?

我正在用 ruby​​ 编写一个简单的在线商店,但在项目过滤方面遇到了问题。 我正在尝试通过几个选项过滤项目(例如“颜色”:“红色”和“品牌”:“zara”)。

我希望只看到同时具有“红色”和“zara”选项的项目。

当我按一个选项过滤时,一切正常。 但由于选项很少,它会显示至少具有其中一个选项的所有项目。

我在项目模型中的过滤范围:

scope :by_options,
    ->(options) { joins(:items_options).where(items_options: { option_id: options }).distinct }

物品控制器:

class ItemsController < ApplicationController
  def index
    @items = Item.all

    filtering_params(params).each do |key, value|
      @items = @items.public_send("by_#{key}", value) if value.present?
    end
  end

  private
    def filtering_params(params)
      params.slice(:category, :options)
    end
  end

生成的查询:

SELECT DISTINCT "items".* FROM "items" INNER JOIN "items_options" ON "items_options"."item_id" = "items"."id" WHERE "items_options"."option_id" IN (?, ?)  [["option_id", 1], ["option_id", 6]]

我还尝试按选项过滤两次,但在这种情况下,@items 为空(6 和 1 只是示例,因为我的项目同时具有这两个选项:

@items = Item.by_options(6).by_options(1)

生成的查询:

SELECT DISTINCT "items".* FROM "items" INNER JOIN "items_options" ON "items_options"."item_id" = "items"."id" WHERE "items_options"."option_id" = ? AND "items_options"."option_id" = ?  [["option_id", 6], ["option_id", 1]]

数据库架构:

create_table "items", force: :cascade do |t|
  t.string "name", null: false
  t.decimal "price", null: false
  t.integer "available_count", null: false
  t.integer "category_id"
  t.datetime "created_at", precision: 6, null: false
  t.datetime "updated_at", precision: 6, null: false
  t.index ["category_id"], name: "index_items_on_category_id"
end

create_table "items_options", id: false, force: :cascade do |t|
  t.integer "item_id", null: false
  t.integer "option_id", null: false
end

create_table "options", force: :cascade do |t|
  t.string "name", null: false
  t.integer "filter_id"
  t.datetime "created_at", precision: 6, null: false
  t.datetime "updated_at", precision: 6, null: false
  t.index ["filter_id"], name: "index_options_on_filter_id"
end

你可以试试:

scope :by_options,
    ->(options) { 
          self.joins(:items_options)
              .having('SUM(items_options.option_id in (?)) = ?', options, options.size)
     }

您基本上是在说:“给我所有具有我指定的所有 items_options.option_id 的项目”。

这有点脏,我还没有测试过,但从我的头顶来看,它应该可以解决问题。

否则,您介意将 SQL 模式创建语句链接到您的帖子,以便我们可以更轻松地运行查询吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM