编写检查模型和数据库的rake然后更新另一个模型

时间:2014-01-09 06:17:56

标签: mysql sql ruby-on-rails

我正在试图找出如何编写一个rake任务,该任务将采用模型Subscription并检查数据库中每行的每一列。列日期为false的任何行,它会更新User model属性。到目前为止我已经:

task :check_subscription => :environment do

@subscription = Subscription.find(:all)
for_each @subscription do |sub|
    Date.today.strftime('%Y-%m-%d') == sub.expiry_date.strftime('%Y-%m-%d')
end
if false
    User.subscription.user_id.update_attributed(:plan_id => '200')
end
end

不是真的有效,我确定我做得不对。

  1. 我有两个名为Subscription.rb和User.rb
  2. 的模型
  3. DB中的订阅有一个名为expiry_date
  4. 的列
  5. 用户有一个列plan_id,如果他们的订阅为假(已过期),则应更新为'200'。
  6. 订阅包含列user_id,订阅模型包含belongs_to User

2 个答案:

答案 0 :(得分:1)

task :check_subscription => :environment do
   # Select expired subscriptions
   expired_subscriptions = Subscription.where("expiry_date < ?", Time.now.beginning_of_day)
   # Select user ids of all expired subscriptions.
   expired_subscription_user_ids = expired_subscriptions.pluck(:user_id)
   # Update all users with id = expired_subscription_user_ids so that their plan_id is 200
   User.update_all({:plan_id => '200'}, {:id => expired_subscription_user_ids})

   # Delete the expired subscriptions
   expired_subscriptions.delete
end

答案 1 :(得分:0)

您可以在一个语句中使用update_all执行此操作:

User.joins(:subscriptions).where("subscriptions.expiry_date < ?", Time.now.beginning_of_day).update_all("users.plan_id = 200")

其他一些想法/想法:

  1. 您也可以只执行一个纯SQL更新语句
  2. 如果这是一次性转换,则应该是迁移而不是独立的rake任务
  3. 如果这是一个经常发生的事情,你需要包含一些可以调用任务的调度组件。