在acts-as-taggable-on中,如何获取MyModel所有实例的全部标签?
问题:获取MyModel实例使用的所有标签
我的模型定义如下:
class MyModel < ApplicationRecord acts_as_taggable_on :tags end
想知道怎么获取该模型所有实例使用的全部tags?
我试过几种方法,但都有问题:
- 方法一:
MyModel.tags_on(:tags).pluck(:name)
虽然能得到结果,但生成的SQL会把模型所有实例的ID塞进IN子句,查询效率很低,SQL语句如下:
SELECT tags.* FROM `tags` JOIN (SELECT `taggings`.`tag_id` FROM `taggings` WHERE (taggings.taggable_type = 'MyModel') AND (taggings.taggable_id IN ( **[ALL THE IDS]** ) GROUP BY `taggings`.`tag_id`) AS taggings ON taggings.tag_id = tags.id
- 方法二:
MyModel.all_tags.pluck(:name)
和方法一问题一样,SQL会包含所有实例ID。
- 方法三:
ActsAsTaggableOn::Tag.for_context(:tags).pluck(:name)
这个方法返回的是所有使用:tags上下文的模型的标签,不只是MyModel的。
正确解法
可以直接通过关联查询过滤出属于MyModel的标签,避免生成包含大量ID的IN子句,推荐两种写法:
写法一:从Tag表关联查询
ActsAsTaggableOn::Tag.joins(:taggings) .where(taggings: { taggable_type: 'MyModel', context: 'tags' }) .distinct .pluck(:name)
写法二:从Tagging表关联查询
ActsAsTaggableOn::Tagging.where(taggable_type: 'MyModel', context: 'tags') .joins(:tag) .distinct .pluck('tags.name')
这两种方式都会直接过滤taggings表中属于MyModel且上下文为tags的记录,通过distinct确保标签不重复,查询效率更高,也不会出现包含所有实例ID的问题。
内容的提问来源于stack exchange,提问作者fguillen
相关产品推荐
相关产品推荐

