1

我正在使用acts-as-taggable-on宝石,并希望在ActsAsTaggableOn :: Tag上实现一个名为#related_tags的关联。在Rails ActiveRecord has_many关联上自定义查询

这种方法的要点是我想返回所有标记,并与我选择的任何特定标记串联在一起。例如,给定下列:

Tags 
id name 
1 happy 
2 bright 
3 warm 

Posts 
id tags 
1 happy,bright 
2 bright,warm 

然后ActsAsTaggableOn :: Tag.find(1).related_tags应包括标签实例为明亮的(2),但ActsAsTaggableOn :: Tag.find(2).related_tags应包括快乐和温暖的实例(1和3)。

我得到的SQL在SQL壳的工作,那就是:

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]] 

所以这里的问题是额外的“标签”。“id”= $ 1其中$ 1是目前的标签ID ...但我不知道如何增加或如何取消它。如果我采取生成的SQL并删除该条件,它工作正常。其他人是否知道为什么会添加以及如何摆脱它?

Relevant docs are here,但没有太大的帮助。

提前致谢!

+0

顺便说一下,我知道我可以制作一个实现上述sql的实例方法,但我渲染标签的集合,因此能够使用:: includes同时预取所有标签将是很好的选择。 – rurabe

回答

0

我有一个问题,我通过关系在has_many上做了一个。例如:Update.first.tags.where(...)。我发现的是,它只查询与该更新相关的标签。所以这个调用首先查询当前与Update.first相关的标签,然后是我的SQL查询。

你的情况可能会发生类似的情况。

此外,你有兴趣的另一点,标签:tag.id.那些是我能想到的唯一的两个点,那就是添加“标签”。“id”= $ 1