使用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)。
一种方法是使用外连接和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]]