Rails / SQL帮助:三个表,按另一个记录的存在进行选择和排序

问题描述 投票:-1回答:1

使用ActsAsTaggableOn gem,可标记对象是Template。加上这些联想:

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

目标:准备分页的模板集合,用户选择标记,我们找到与该标记匹配的所有模板,并根据引脚中是否存在相同的标记和模板对其进行排序。

编辑 - 简化和释义。

鉴于模板标记有标签,并且那些标签可能有也可能没有Pin,我需要选择所有带有X标签的模板,并对它们进行排序,无论该标签是否有Pin(布尔排序,顶部为trues)。

sql ruby-on-rails activerecord rails-activerecord querying
1个回答
0
投票

一种方法是使用外连接和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]]
© www.soinside.com 2019 - 2024. All rights reserved.