我有一个printContent('Ticket12345')
模型。每个Node
对象都有一个名为node
或user_tags
的虚拟属性,该属性继承自user_tag_list
。
看起来像这样:
acts_as_taggable
我想要做的是创建一个范围,该范围返回已在节点上标记的所有用户记录。即他们的电子邮件会显示在某些[24] pry(main)> n
=> #<Node id: 85, name: "House Fire 2", family_tree_id: 57, user_id: 57, media_id: 228, media_type: "Video", created_at: "2015-05-15 00:20:26", updated_at: "2015-05-20 01:06:34", circa: nil, is_comment: nil, cached_votes_total: 0, cached_votes_score: 0, cached_votes_up: 0, cached_votes_down: 0, cached_weighted_score: 0, cached_weighted_total: 0, cached_weighted_average: 0.0>
[25] pry(main)> n.user_tags
ActsAsTaggableOn::Tag Load (4.0ms) SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = $1 AND "taggings"."taggable_type" = $2 AND "taggings"."context" = 'user_tags' [["taggable_id", 85], ["taggable_type", "Node"]]
=> [#<ActsAsTaggableOn::Tag id: 4, name: "gerry@test.com", taggings_count: 1>, #<ActsAsTaggableOn::Tag id: 6, name: "danny@test.com", taggings_count: 1>]
[26] pry(main)> n.user_tag_list
=> ["gerry@test.com", "danny@test.com"]
或n.user_tags
的列表中。
我试过这个:
n.user_tag_list
这个问题是这只适用于1 scope :with_tagged_users, -> (node) { node.user_tag_list.collect do |tag|
User.find_by email: tag
end
}
个对象。即我必须做node
,这有点违背了在整个模型上使用范围的目的。
我还可以对所有节点进行迭代,然后检查每个节点上是否Node.tagged_users(node)
,但这似乎并不高效。
我觉得应该有一种方法可以使用user_tags.empty?
或joins
或其他一些应该能够简单地执行此操作的内置方法。很快,但我无法想出来。
因此,为了清楚起见,理想情况下我想做includes
并且应该返回在任何节点上标记的所有用户的列表,最好没有重复。
答案 0 :(得分:1)
我不知道acts_as_taggable的确切表格,但我认为它们的名称是:“taggings”和“tags”
知道你可以这样做:
获取所有代码
ActsAsTaggableOn::Tag.where("id in (?)", ActsAsTaggableOn::Tagging.where(taggable_type: 'Node').pluck(:tag_id))
获取具有标记的节点
Node.where("id in (?)", ActsAsTaggableOn::Tagging.where(taggable_type: 'Node').pluck(:taggable_id))
def self.with_tagged_users
Node.where("id in (?)", ActsAsTaggableOn::Tagging.where(taggable_type: 'Node').pluck(:taggable_id))
end
答案 1 :(得分:0)
我认为这只是一个实例方法而不是范围,但这里的范围是第一个:
scope :with_tagged_users, -> (node) { User.find_by email: node.user_tag_list }
同样,这里的查询是Node
上的实例方法:
def tagged_users
User.find_by email: user_tag_list
end
答案 2 :(得分:0)
您可能会发现squeel gem很有帮助。我认为它的过滤器&#39; sifter&#39;功能可能允许您实现目标。我有空的时候会尝试一个例子。
答案 3 :(得分:0)
上述Cristi方法的替代方案只是添加名为cache_column
的{{1}}。
然后我必须确保在添加和删除标记时添加逻辑以递增或递减。
但在我的范围内,我只是做了类似的事情:
cached_num_user_tags
所以,授予......它对实际属性进行查询,而不是像我最初问过的那样的虚拟属性....但它给了我一个可行的解决方案。