我正在用红宝石写一个简单的在线商店,物品过滤有问题。我正在尝试通过几种选项(例如'颜色':'红色'和'品牌':'zara')过滤项目。
我希望只看到同时具有'red'和'zara'选项的项目。
当我按一个选项过滤时,一切都很好。但是只有很少的选项,它将显示所有具有至少一个选项的项目。
我在Item模型中的过滤范围:
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模式创建语句链接到您的帖子,以便我们可以更轻松地运行查询吗?