Rails "acts-as-taggable-on": how to add tag *objects* to taggables, not by name
Asked Answered
A

1

11

In a data importer, I have code which is attempting to add a bunch of ActsAsTaggableOn::Tag objects to a taggable's tag list:

    existing_item = FeedItem.where(url: item[:url]).first

    if existing_item.nil?
      new_item = FeedItem.new

      new_item.attributes = item.except(:id, :feeds)

      new_item.feeds = Feed.where(id: feeds_old_to_new(item_feeds, feeds))
      new_item.tag_list.add(
          ActsAsTaggableOn::Tag.where(id: tags_old_to_new(item[:tags], tags)))

      new_item.save!
   else
      # ... merge imported record with existing item ...
   end

This doesn't work, because tag_list.add takes a list of tag names, not tag objects. Is there any way to add tag objects? I can't find anything in the acts-as-taggable-on documentation, and its code is much too magic for me to understand (for instance, Tag::concat doesn't appear to mutate self!)

I could map the tags to their names, but then acts-as-taggable-on would run name canonicalization that is appropriate for user input but not for bulk data import, so I don't want to do that.

Antimony answered 10/12, 2017 at 15:16 Comment(0)
S
3

The gem is really just adding this for you:

has_many :taggings
has_many :tags, through: :taggings

(It's a little more complicated to support multiple kinds of tags, but the details are pretty simple.)

So you can use those associations just like any other. In your case it'd be something like:

ActsAsTaggableOn::Tag.where(id: tags_old_to_new(item[:tags], tags))).each do | t|
  new_item.tags << t
end
Sheugh answered 16/1, 2018 at 22:46 Comment(6)
I have a distinct recollection of doing something that led me to believe that FeedItem objects do not have a tags property. There are some weird things in the definition of FeedItem - look specifically at what it's doing with :tag_context_hierarchy. Can you offer any additional advice on what might need to be changed in your answer to cope with that?Antimony
It has a simple acts_as_taggable declaration. I don't see anything in tag_context_hierarchy to change that. You can see that it even uses the tags association itself.Sheugh
Hmm, OK. That's enough information that I can believe this ought to work. I timed the bounty badly; I won't be able to test this for another month or so. I'm going to go ahead and give the bounty to you, but not accept the answer until I've actually tested it.Antimony
For the record, this is the weird thing I was concerned about.Antimony
I don't think you need to be concerned about that. acts_as_api controls how instances are serialized to JSON when rendering an HTTP response, but it doesn't replace the tags method. (Right? I haven't used it, but I glanced at its docs.)Sheugh
Your guess is probably better than mine - I don't even really speak Ruby. In retrospect, attempting to build on this particular Rails app may have been a mistake.Antimony

© 2022 - 2024 — McMap. All rights reserved.