ActiveRecord - 如何“选择”多态连接作为布尔值?

时间:2015-07-16 21:35:07

标签: ruby-on-rails postgresql activerecord

我一直在试图提出这个问题时撞墙,所以我觉得是时候在这里发帖了。

我有一个名为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尝试了这些建议,但似乎没有任何建议。

谢谢!

1 个答案:

答案 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感兴趣,所以我们只检查子查询中的表并使用主查询中的结果。

现在我把它写出来是有意义的,但是我会把它放在这里以防万一其他人得到同样的愚蠢。