1

我在 Rails (Ruby 1.9.3) 项目上使用acts_as_taggable_on gem。我向我的管理员提供了一个表单,以将 1..n 标记添加到资源列表(假设是客户端)。

我没有找到批量执行此操作的方法。现在我在每个客户端上循环并添加一个标签然后保存对象。当我在 X 千个客户端上尝试时,这对服务器造成了很大的伤害,最终造成了超时。

我想知道是否有办法将标签应用于 ActiveRecord 集合或其他东西。如果记录在案,我深​​表歉意,但我在任何地方都找不到这样做的人。

我可以通过自己执行自定义 SQL 查询来了解如何破解它,但我更愿意避免像这样破解 gem,ofc。

现在我正在做这样的事情

像这样的东西

# 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

非常感谢您的时间。

额外:好吧,我也需要能够将 1..n 个标签删除到一个集合中!

4

2 回答 2

2

直接使用标记模型。可以使用以下内容(假设可标记对象属于同一类)

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

删除就简单多了

Taggings.where(:taggable_type => "Client", :taggable_id => client_ids, :tag_id => tag_ids).delete_all
于 2012-09-28T15:52:57.733 回答
2

受 Saverio answser 的启发,我终于用add_tagsremove_tags方法扩展了 ActiveRecord::Relation。

这是一个例子:

# 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')

我为该补丁创建了一个Github 存储库,希望对您有所帮助!

谢谢您的帮助!

于 2012-10-03T09:52:19.337 回答