I have a Node
model. Each node
object has a virtual attribute called user_tags
or user_tag_list
which was inherited from acts_as_taggable
.
It looks like this:
[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"]
What I would like to do is create a scope that returns all user records that have been tagged on a node. i.e. where their email would appear in the list of some n.user_tags
or n.user_tag_list
.
I have tried this:
scope :with_tagged_users, -> (node) { node.user_tag_list.collect do |tag|
User.find_by email: tag
end
}
The issue with this is that this is just for 1 node
object. i.e. I would have to do Node.tagged_users(node)
which kinda defeats the purpose of having a scope on the entire model.
I could also do an iteration through all the nodes and check to see if user_tags.empty?
on each, but that doesn’t seem performant.
I feel like there should be a way to do this with either joins
or includes
or some other built-in method that should be able to do this simply & fast, but I can’t quite come up with it.
So, to be clear, ideally I would like to do Node.with_tagged_users
and that should return a list of all the users that are tagged on any node, preferably with no duplicates.
P.S. I also have this on SO, if you want SO points for the solution - ruby on rails - How do I create a performant scope based on the virtual attributes of an associated model? - Stack Overflow