查看给定植物药的展示页面时,我想显示一个包含该特定植物药的杜松子酒列表。
简单。就这样吧:
@botanical = Botanical.includes(:gins).find(params[:id])
@gins = @botanical.gins
如果您已经有 id,则无需 LIKE 查询。而且由于您已经设置了间接关联,因此您可以使用它来获取杜松子酒。
如果您真正想要的是获得与给定杜松子酒具有共同植物成分的其他杜松子酒,您可以这样做:
class Gin < ApplicationRecord
has_many :gin_botanicals
has_many :botanicals, through: :gin_botanicals
def similiar_gins
Gin.joins(:botanicals)
.where(botanicals: { id: self.botanical_ids })
.where.not(id: self.id)
end
end
.joins 创建一个左内连接 - 因此连接表中没有匹配的所有行都将被丢弃。
.where(botanicals: { id: self.botanical_ids }) 创建一个WHERE IN 查询,要求连接的记录至少有一个共同的植物。
您还可以使用 GROUP BY 和 HAVING 设置所需的相似度:
class Gin < ApplicationRecord
has_many :gin_botanicals
has_many :botanicals, through: :gin_botanicals
def similiar_gins(common_ingredients: 1)
Gin.joins(:botanicals)
.where(botanicals: { id: self.botanical_ids })
.where.not(id: self.id)
.group("gins.id")
.having("COUNT(distinct botanicals.id) >= ?", common_ingredients)
end
end
给定:
irb(main):039:0> Gin.all.pluck(:id, :name)
(1.1ms) SELECT "gins"."id", "gins"."name" FROM "gins"
=> [[1, "Beefeater Gin"], [2, "Bombay Sapphire"], [3, "Mockinghamshire"]]
irb(main):040:0> Botanical.all.pluck(:id, :name)
(1.1ms) SELECT "botanicals"."id", "botanicals"."name" FROM "botanicals"
=> [[1, "Almond"], [2, "liquorice"], [3, "Foo"]]
irb(main):041:0> GinBotanical.all.pluck(:gin_id, :botanical_id)
(0.5ms) SELECT "gin_botanicals"."gin_id", "gin_botanicals"."botanical_id" FROM "gin_botanicals"
=> [[1, 1], [2, 1], [1, 3], [1, 2], [2, 2]]
含有 2 种常见成分:
irb(main):036:0> Gin.first.similiar_gins(common_ingredients: 2)
Gin Load (1.2ms) SELECT "gins".* FROM "gins" ORDER BY "gins"."id" ASC LIMIT $1 [["LIMIT", 1]]
(4.0ms) SELECT "botanicals".id FROM "botanicals" INNER JOIN "gin_botanicals" ON "botanicals"."id" = "gin_botanicals"."botanical_id" WHERE "gin_botanicals"."gin_id" = $1 [["gin_id", 1]]
Gin Load (4.3ms) SELECT "gins".* FROM "gins" INNER JOIN "gin_botanicals" ON "gin_botanicals"."gin_id" = "gins"."id" INNER JOIN "botanicals" ON "botanicals"."id" = "gin_botanicals"."botanical_id" WHERE "botanicals"."id" IN (1, 2, 3) AND ("gins"."id" != $1) GROUP BY gins.id HAVING (COUNT(distinct botanicals.id) >= 2) [["id", 1]]
=> #<ActiveRecord::Relation [#<Gin id: 2, name: "Bombay Sapphire", created_at: "2018-03-07 23:44:43", updated_at: "2018-03-07 23:44:43">]>
但如果我们将其设置为 3,我们会得到一个空集:
irb(main):037:0> Gin.first.similiar_gins(common_ingredients: 3)
Gin Load (0.7ms) SELECT "gins".* FROM "gins" ORDER BY "gins"."id" ASC LIMIT $1 [["LIMIT", 1]]
(1.8ms) SELECT "botanicals".id FROM "botanicals" INNER JOIN "gin_botanicals" ON "botanicals"."id" = "gin_botanicals"."botanical_id" WHERE "gin_botanicals"."gin_id" = $1 [["gin_id", 1]]
Gin Load (5.0ms) SELECT "gins".* FROM "gins" INNER JOIN "gin_botanicals" ON "gin_botanicals"."gin_id" = "gins"."id" INNER JOIN "botanicals" ON "botanicals"."id" = "gin_botanicals"."botanical_id" WHERE "botanicals"."id" IN (1, 2, 3) AND ("gins"."id" != $1) GROUP BY gins.id HAVING (COUNT(distinct botanicals.id) >= 3) [["id", 1]]
=> #<ActiveRecord::Relation []>