简体   繁体   English

在Rails ActiveRecord has_many关联上定制查询

[英]Customizing the query on a Rails ActiveRecord has_many association

I am using the acts-as-taggable-on gem and want to implement an association on ActsAsTaggableOn::Tag called #related_tags. 我正在使用acts-as-taggable-on gem,并想在ActsAsTaggableOn :: Tag上实现一个名为#related_tags的关联。

The gist of this method is that I want to return all tags that have been tagged in tandem with any specific tag of my choosing. 该方法的要点是我想返回所有与我选择的任何特定标签一前一后标记的标签。 For example, given the following: 例如,给出以下内容:

Tags
id  name
1   happy
2   bright
3   warm

Posts
id  tags
1   happy,bright
2   bright,warm

Then ActsAsTaggableOn::Tag.find(1).related_tags should include the Tag instances for bright (2), but ActsAsTaggableOn::Tag.find(2).related_tags should include both the instances for happy and warm (1 and 3). 然后,ActsAsTaggableOn :: Tag.find(1).related_tags应该包括明亮(2)的Tag实例,但是ActsAsTaggableOn :: Tag.find(2).related_tags应该包括快乐和热情的两个实例(1和3)。

I got the sql working in a sql shell, which is: 我在sql shell中使用了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});

and tried to add it to the association as such: 并尝试将其添加到关联中:

ActsAsTaggableOn::Tag.class_eval do
   has_many :related_tags, ->(tag) { where( <above sql>, :tag => tag.id) },:class_name => "ActsAsTaggableOn::Tag", :foreign_key => 'id'
end

Which seems like it should work to me... but the SQL that it generates is: 似乎应该对我有用...但是它生成的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]]

So the problem here is the extra "tags"."id" = $1 where $1 is the current tag id... but I don't know how that is getting added or how to take it off. 因此,这里的问题是多余的“标签”。“ id” = $ 1,其中$ 1是当前标签ID ...,但我不知道该如何添加或如何删除它。 If I take the generated sql and remove that criteria, it works fine. 如果我采用生成的sql并删除该条件,则可以正常工作。 Does anyone else know why this is added and how to get rid of it? 还有谁知道为什么要添加它以及如何摆脱它吗?

Relevant docs are here , but aren't of much help. 相关文档在这里 ,但没有太大帮助。

Thanks in advance! 提前致谢!

I had a problem where I was doing a .where on a has_many through relationship - for example: Update.first.tags.where(...). 我在通过关系在has_many上执行.where时遇到问题-例如:Update.first.tags.where(...)。 What I found out is that it was only querying tags already associated with that Update. 我发现这只是在查询已经与该更新关联的标签。 So the call was first querying Tags currently associated with Update.first, then my SQL query. 因此,调用首先是查询当前与Update.first关联的标签,然后是我的SQL查询。

Something similar could be happening in your case. 在您的情况下,可能会发生类似的情况。

Also, another point of interest you have , tag: tag.id. 另外,您还有另一个有趣的地方,tag:tag.id。 Those are the only two spots I can think of that would be adding the "tags"."id" = $1 那是我能想到的仅有的两个地方,那就是添加“标签”。“ id” = $ 1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM