gpt4 book ai didi

ruby-on-rails - 模型中匹配所有关联值的方法

转载 作者:太空宇宙 更新时间:2023-11-03 16:04:07 24 4
gpt4 key购买 nike

我有一个模型,其中我尝试“匹配所有”用户选择的标签。但是,一旦我在我的应用程序中选择了两个标签,并将参数传递给下面的方法,它就不会返回任何结果。一种选择效果很好。

如您所见,我有一个 Style 模型,它通过 Tagizations 有_many Tags。我想“匹配所有”用户选择的标签,我在 filter_with_params 定义下的第三行是我尝试进行正确的查询。

因此,如果我将 params[:t] = ["green", "yellow", "red"] 传递给过滤器方法,我只想返回具有所有这三个标签的样式.

这是模型的一个片段:

class Style < ActiveRecord::Base
has_many :tagizations, :dependent => :destroy
has_many :tags, :through => :tagizations

def self.filter_with_params(params)
scoped = self.where("styles.name != ''")
scoped = scoped.includes(:tags)
scoped = params[:t].inject(scoped){|memo, val| memo.where(:tags => {:name => val})} if params[:t]
scoped
end
end

这是一个包含两个请求的开发日志输出的 Gist:

https://gist.github.com/jgrannas/6195528

使用 .TO_SQL

单一标签(有效):

Style.filter_with_params({:t => ["engagement"]}).to_sql
=> "SELECT \"styles\".* FROM \"styles\" WHERE \"tags\".\"name\" = 'engagement' AND (styles.name != '')"

多个标签(不起作用)

Style.filter_with_params({:t => ["engagement", "Halo"]}).to_sql
=> "SELECT \"styles\".* FROM \"styles\" WHERE \"tags\".\"name\" = 'engagement' AND \"tags\".\"name\" = 'Halo' AND (styles.name != '')

我正在使用 postgres

最佳答案

这是你的问题:

WHERE "tags"."name"= 'engagement' AND "tags"."name"= 'Halo'

问题是您正在寻找具有单个 标签和所有 3 个名称的东西,这是不可能的。您想要的是每个名称都有一个标签的东西。

不完全确定这是否有效,但请尝试以下操作:

def self.filter_with_params(params)
scoped = self.select("distinct styles.*, count(*) AS count")
scoped = scoped.where("styles.name != ''")
scoped = scoped.joins(:tags)
if params[:t]
scoped = scoped.where(tags: { name: params[:t] })
scoped = scoped.group('styles.id')
scoped = scoped.having("count = #{params[:t].size}")
end
scoped
end

我们在这里所做的基本上是我们正在构建一个表,其中一行包含每个样式标签组合,但仅针对 params[:t]< 中的标签。因此,例如,我们将有一行用于 style1 - tag1,另一行用于 style1 - tag2。然后我们按样式 id 对行进行分组,这样我们只为每种独特的样式获得一条记录。但我们也在计算每组中有多少行。我们只想要标签集中的每个标签都有一行的记录,因此我们丢弃其余的。

注意:以上代码适用于 MySQL,但不适用于 postgres。 The documentation for postgres SELECT说:

"An output column's name can be used to refer to the column's value in ORDER BY and GROUP BY clauses, but not in the WHERE or HAVING clauses; there you must write out the expression instead."

所以我们需要 scoped = scoped.having("count(*) = #{params[:t].size}")

关于ruby-on-rails - 模型中匹配所有关联值的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18152587/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com