Mongoid是否可以覆盖updated_at时间戳

时间:2018-04-23 17:16:26

标签: ruby mongodb ruby-on-rails-4 mongoid

我正在尝试通过rake任务手动编辑“updated_at”字段

这是它的样子:

task :campaigns_updated_at_recovery => :environment do

Dir.foreach('db/raw-data/campaigns/') do |json|
  next if json == '.' or json == '..'
  file = File.read('db/raw-data/campaigns/'+json)
  data_hash = JSON.parse(file)
  #p data_hash["_id"]
  thisCampaign = Campaign.find(data_hash["_id"])
  thisCampaign["channels"].each do |chan|
    if chan["updated_at"] < Date.new(2018,04,19)
      data_hash["channels"].each do |channel|
        if chan["_id"].to_s == channel["_id"]
          chan["updated_at"] = Date.parse(channel["updated_at"])
        end
      end
    end
    thisCampaign.save
  end
end

但是,当我运行此任务时,updated_at日期要么没有更改,要么更新到今天的日期。 我错过了什么?

我正在使用Mongoid而不是ActiveRecord

1 个答案:

答案 0 :(得分:1)

updated_at由mongoid本身在回调中更新。

你有两种解决方案可以解决这个问题。

最简单的解决方案是使用set直接更改值而不触发任何回调:

thisCampaign.set(channels: thisCampaign['channels'])

更灵活的解决方案是降低到驱动程序级别。基本思路是:

Campaign.collection.find(_id: data_hash["_id"]).update_one({
  '$set' => {
    updated_at: yourDate
  }
})

根据您的示例,您首先需要获取完整的文档

thisCampaign = Campaign.collection.find(_id: data_hash["_id"]).first
if thisCampaign
  thisCampaign["channels"].each do |chan|
    if chan["updated_at"] < Date.new(2018,04,19)
      data_hash["channels"].each do |channel|
        if chan["_id"].to_s == channel["_id"]
          chan["updated_at"] = Date.parse(channel["updated_at"])
        end
      end
    end
  end
  Campaign.collection.find(_id: data_hash["_id"]).update_one({
    '$set' => {channels: thisCampaign["channels"]}
  })
end