【发布时间】:2013-12-07 21:28:48
【问题描述】:
我正在使用 acts-as-taggable-on gem 并希望在 ActsAsTaggableOn::Tag 上实现一个名为 #related_tags 的关联。
此方法的要点是,我想返回与我选择的任何特定标签一起标记的所有标签。例如,给定以下内容:
Tags
id name
1 happy
2 bright
3 warm
Posts
id tags
1 happy,bright
2 bright,warm
那么 ActsAsTaggableOn::Tag.find(1).related_tags 应该包含 Bright (2) 的 Tag 实例,但是 ActsAsTaggableOn::Tag.find(2).related_tags 应该包含happy 和 warm (1 和3).
我让 sql 在 sql shell 中工作,即:
SELECT * FROM tags WHERE id IN (SELECT tags.id FROM taggings JOIN tags ON tags.id = taggings.tag_id WHERE taggings.taggable_id IN (SELECT taggable_id FROM taggings WHERE taggings.tag_id = #{tag.id}) AND tags.id <> #{tag.id});
并尝试将其添加到关联中:
ActsAsTaggableOn::Tag.class_eval do
has_many :related_tags, ->(tag) { where( <above sql>, :tag => tag.id) },:class_name => "ActsAsTaggableOn::Tag", :foreign_key => 'id'
end
这似乎对我有用...但它生成的 SQL 是:
SELECT "tags".* FROM "tags" WHERE "tags"."id" = $1 AND (tags.id IN (SELECT tags.id FROM taggings JOIN tags ON tags.id = taggings.tag_id WHERE taggings.taggable_id IN (SELECT taggings.taggable_id FROM taggings WHERE taggings.tag_id = 10) AND tags.id <> 10)) [["id", 10]]
所以这里的问题是额外的 "tags"."id" = $1 其中 $1 是当前标签 id...但我不知道它是如何添加的或如何删除它。如果我采用生成的 sql 并删除该条件,它就可以正常工作。有其他人知道为什么要添加它以及如何摆脱它吗?
Relevant docs are here,但没有多大帮助。
提前致谢!
【问题讨论】:
-
顺便说一句,我知道我可以创建一个实例方法来实现上面的 sql,但是我正在渲染标签集合,所以最好能够使用 ::includes 来预取他们都在同一时间。
标签: sql ruby-on-rails activerecord associations acts-as-taggable-on