Rails/SQL 帮助:三个表,select 并按是否存在另一条记录进行排序

Rails/SQL help: three tables, select and sort by presence of another record

使用 ActsAsTaggableOn gem,可标记对象是模板。 加上这些协会:

class Template
  acts_as_taggable
  has_many :template_designs
end

class Pins
  belongs_to :template
  belongs_to :tag
end

class Tags
  has_many :taggings
end

目标:一组准备好分页的模板,其中用户 selects 一个标签,我们找到所有与该标签匹配的模板,并根据是否存在相同的标签和模板对它们进行排序,如果为真在上面。

编辑 - 简化和释义。

鉴于模板带有标签,并且这些标签可能有也可能没有 Pin,我需要 select 所有带有 X 标签的模板,并根据该标签是否有 Pin(布尔值)对它们进行排序排序,真在上)。

一种方法是将外部联接与 CASE WHEN EXISTS 表达式一起使用:

select templates.*, case when exists 
  (select pins.id 
    from pins 
    where pins.tag_id = tags.id 
    and pins.template_id = templates.id) then true else false end as pinned 
  from templates, taggings, tags, pins 
  where templates.id = taggings.template_id 
  and taggings.tag_id = tags.id 
  and tags.name = 'funny';

这是一个 Active Record 语法:

>> Template.left_outer_joins(:tags)
.where(tags: {name: 'funny'})
.select(:id, :name, 
"case when exists 
  (select pins.id from pins 
  where pins.tag_id = tags.id 
  and pins.template_id = templates.id)
  then true else false end as pinned")
.map {|t| [t.id, t.name, t.pinned] }
[... sql output ...]
=> [[1, "template1", true], [2, "template2", false]]