Add N tags to a LOT of objects using acts_as_taggable_on

别说谁变了你拦得住时间么 提交于 2019-12-24 14:50:35

问题


I'm using the acts_as_taggable_on gem on a Rails (Ruby 1.9.3) project. I provide a form to my admins to add 1..n tag(s) to list of resources (let's say clients).

I didin't find a way to do this in bulk. Right now I'm looping on every client and add one tag then save the object. This is hurting the server a lot when I'm trying on X thousand clients, eventually creating a timeout.

I was wondering if there is a way to apply a tag to an ActiveRecord collection or something. If this is documented I'm deeply sorry, but I can't find somebody doing it anywhere.

I can see how to hack it by doing a custom SQL query all by myself, but I prefer to avoid hacking the gem like this, ofc.

Right now I'm doing something like this

Something like this

# Client.selection returns a clients collection
Client.selection.each do |client|
  tags_to_add.each{|a| client.tag_list << a}
  tags_to_remove.each{|a| client.tag_list.remove(a)}
  client.save
end

Thanks a lot for your time.

Extra: well, I need to be able to remove 1..n tag(s) to a collection too!


回答1:


Use directly the Tagging model. Something like the following could be used (suppose the taggable objects are of the same class)

Tagging.transaction do
  client_ids.each do |cid|
    tag_ids.each do |tid|
      values = ["Client".inspect, cid, tid].join(", ")
      Tagging.connection.execute "INSERT INTO taggings (taggable_type, taggable_id, tag_id) VALUES (#{values}) ON DUPLICATE KEY UPDATE id=id"
    end
  end
end

The deletion is much simpler

Taggings.where(:taggable_type => "Client", :taggable_id => client_ids, :tag_id => tag_ids).delete_all



回答2:


Inspired by Saverio answser, I finally extended ActiveRecord::Relation with add_tags and remove_tags methods.

Here is an example:

# Our ActiveRecord::Relation
clients = Client.where('created_at > ?', Time.now - 2.months)
# Our tags
tags_to_add = ['here','a','bunch','of','tags']
tags_to_remove = ['useless','now']
# Adding and removing tags
# (You can specify the tagging context as a second parameter) 
clients.add_tags(tags_to_add).remove_tags(tags_to_add, 'jobs')

I created a Github repo for the patch, hope this can help!

Thanks for the help!



来源:https://stackoverflow.com/questions/12642950/add-n-tags-to-a-lot-of-objects-using-acts-as-taggable-on

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!