【问题标题】:Erase records every 60 days每 60 天擦除一次记录
【发布时间】:2012-12-20 15:27:09
【问题描述】:

如果记录从 created_at 日期起超过 60 天,我需要删除优惠模型中的记录。

我只找到了有关如何使用 rake 任务填充模型的信息,但找不到有关如何创建 rake 任务以删除记录的信息。所以我只是想知道我是否必须通过一项任务来执行此操作,或者 rails 是否还有其他事情可以执行此操作。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.2


    【解决方案1】:

    为任务创建一个文件:

    # lib/tasks/delete_old_records.rake
    namespace :delete do
      desc 'Delete records older than 60 days'
      task :old_records => :environment do
        Model.where('created_at < ?', 60.days.ago).each do |model|
          model.destroy
        end
    
        # or Model.delete_all('created_at < ?', 60.days.ago) if you don't need callbacks
      end
    end
    

    运行:

    RAILS_ENV=production rake delete:old_records
    

    安排它使用 cron 运行(在本例中每天早上 8 点):

    0 8 * * * /bin/bash -l -c 'cd /my/project/releases/current && RAILS_ENV=production rake delete:old_records 2>&1'
    

    您还可以使用 whenever gem 在部署时创建和管理您的 crontab:

    every 1.day, :at => '8:00 am' do
      rake "delete:old_records"
    end
    

    Github 上了解有关宝石的更多信息。

    【讨论】:

    • 谢谢,我会接受你的回答,并按照 dimuch 在他的回答中所说的那样使用宝石。但我必须再等 4 分钟才能接受你的。
    • ...each(&amp;:destroy) 看起来更漂亮:)
    • @jdoe 它可能看起来更漂亮,但是将数据库操作放在循环中效率低下。 where().destroy, OTOH, 应该 只生成一个 DB 查询(尽管我还没有测试确定!),因此是这样做的正确方法。一般规则:数据库查询不属于循环;相反,请使用数据库的强大功能进行一次大查询。
    • @MarnenLaibow-Koser 我不认为where().destroy 有效。 Model.delete_all('created_at &gt; ?', 60.days.ago) 将是在一个查询中完成所有操作的方法,但这会跳过回调。 destroy_all,没有,但是你又一次加载一条记录。
    • 60.days.ago 生成一个时间戳,2014 年 8 月 8 日星期五 15:57:18 UTC +00:00。因此,如果您想查找较旧的记录,则需要在查询中使用 。
    【解决方案2】:

    60.days.ago 会生成类似的时间戳

    Fri, 08 Aug 2014 15:57:18 UTC +00:00
    

    因此您需要使用

    Online.delete_all("created_at < '#{60.days.ago}'")
    

    这只是 Unixmonkey 的一个小小的疏忽。 我也会使用 delete_all 而不是在一个块中循环每个迭代。

    【讨论】:

      【解决方案3】:

      您可以创建 rake task to delete expired offers ,或为您的商品模型创建类方法并使用例如 whenever gem 调用它。

      【讨论】:

      • 谢谢,我会随时检查
      【解决方案4】:

      您可以像这样在单个查询中删除超过 60 天的所有记录:

      Model.where("created_at < '#{60.days.ago}'").delete_all
      

      【讨论】:

      • delete_all 不会调用任何回调。最好使用destroy_all
      猜你喜欢
      • 2012-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-08
      • 1970-01-01
      相关资源
      最近更新 更多