我一直在试图提出这个问题时撞墙,所以我觉得是时候在这里发帖了。
我有一个名为Flair
的课程 - 它是多态的,因为很多东西可以有天赋:
class Flair < ActiveRecord::Base
belongs_to :flairable, polymorphic: true, touch: true
belongs_to :user
end
Comment
有很多Flairs
:
class Comment < ActiveRecord::Base
has_many :flairs, as: :flairable
end
获取评论列表时,我也想知道哪些评论有一个属于给定用户的Flair。
到目前为止我能想出的最好的是
# don't worry about the interpolation; just for the example
# and assume we have valid @comments and user_id
@comments.select('comments.*').
select('flairs.id as has_flaired').
joins("left join flairs on flairable_id = comments.id and flairs.user_id = #{user_id}")
但是这会为Comment上的每个Flair返回一个结果(正如左边连接所预期的那样),有效地将数组中每个Comment的出现次数乘以它所具有的flairs数量。
我已尝试使用distinct on (user_id)
,应用limit
等,但这些努力只会导致语法错误。
有人可以提供任何指导吗?特别有用的是指向文档中某处的指针,其示例比此处提供的示例更为复杂:http://www.postgresql.org/docs/9.4/static/sql-select.html。我也在http://www.postgresql.org/docs/9.4/static/queries-table-expressions.html尝试了这些建议,但似乎没有任何建议。
谢谢!
答案 0 :(得分:0)
www.postgresql.org/docs/9.4/static/queries-table-expressions.html中的第7.2.1.3节和第一个例子here,一位极度耐心的老板最终帮助解决了这个问题。最后(在敲击键盘一段时间之后),我终于设法用一个语法正确的查询来取悦Postgres / ActiveRecord神(我们正在清理joins
然后将其传递给@comments.select(
"comments.*,
flairs.id as has_flaired"
).joins(
"left join
flairs on flairs.id = (
select id from flairs where flairs.user_id = #{user_id}
and flairs.flairable_id = comments.id
limit 1
)"
)
语句
row/column A B C D
1 fly cat dog fish
2 cat pig horse dog
3 zebra pig cat elephant
这是有效的,因为我只对flairs表中是否存在具有该用户的行和flairable_id感兴趣,所以我们只检查子查询中的表并使用主查询中的结果。
现在我把它写出来是有意义的,但是我会把它放在这里以防万一其他人得到同样的愚蠢。