不使用Rake运行Rake Task

时间:2012-11-20 17:50:13

标签: ruby-on-rails rake helper

我有一个应用程序,用户可以互相打赌,当结果加载到应用程序时,我使用Rake任务来结算投注。我正在Heroku上运行所以我每隔半小时就会使用他们的计划服务来完成这项Rake任务。

这样可以正常工作,但我更希望在数据库中保存/更新结果时运行Rake作业。

如何转换Rake任务,以便我可以从我的模型中运行它,如下所示。如果我可以从控制器运行它也可能很好,因为我可能有几种需要结算过程的情况。

class Spotprice < ActiveRecord::Base
  belongs_to :spotarea
  belongs_to :product

  after_save   :settlement
end

My Rake任务现在看起来像这样:

task :settlement => :environment do
  puts "Settlement in progress..."
  puts "-------------------------"
  puts " "
  puts " "
  puts "BETS:"
  puts "-------------------------"

  # Bet settlement
  @bets = Bet.where(:settled => false)

  @bets.find_each do |bet|

    if not bet.choice.spotprice.nil?

      case 
      when bet.choice.spotprice.value > bet.choice.value && bet.buy == true
        profitloss  = 10
        puts "#{bet.id}: Win (1)"
      when bet.choice.spotprice.value < bet.choice.value && bet.buy == false 
        profitloss  = 10
        puts "#{bet.id}: Win (2)"
      when bet.choice.spotprice.value > bet.choice.value && bet.buy == false
        profitloss  = -10
        puts "#{bet.id}: Loose (3)"
      when bet.choice.spotprice.value < bet.choice.value && bet.buy == true 
        profitloss  = -10
        puts "#{bet.id}: Loose (4)"
      when bet.choice.spotprice.value == bet.choice.value
        profitloss  = -10
        puts "#{bet.id}: Loose (5)"
      end

      if profitloss  
        bet.settled    = true
        bet.profitloss = profitloss 
        bet.save
      end 

    end

    if bet.choice.settled == true
      bet.choice.settled = false
      bet.choice.save
    end

  end

  # Pusher update
  Pusher["actives"].trigger("updated", {:message => "Settlement completed"}.to_json)

end

2 个答案:

答案 0 :(得分:1)

将我对原始问题的评论放到答案中。

我有类似的情况,我有一个rake任务,我想从rake之外调用。你想要做的是将代码从rake任务移到ruby类中,最好的位置是lib。你的课看起来像这样:

# lib/settlement.rb
class Settlement
  def self.settle_bets
    # all the code that used to be in the rake task
  end
end

然后在代码中你可以做这样的事情(随机例子):

# app/controllers/bets_controller.rb
#...
  def settle_bets
    require "settlement"
    Settlement.settle_bets
  end
# ...

或(另一个随机例子):

# app/models/bet.rb
class Bet ...
  after_update: update_some_bets

  # ... more code here

  private
    def update_some_bets
      require "settlement"
      Settlement.settle_bets
    end

如果你愿意,你仍然可以使用rake任务:

# lib/tasks/settlement.task
require "settlement"
# require "#{Rails.root}/lib/settlement.rb" # use this if the above won't work

task :settlement => :environment do
  Settlement.settle_bets
end

答案 1 :(得分:0)

如果您想要在更新(或保存)时计算结果,为什么不将rake任务中的大部分代码移动到Bet模型的方法中,然后使用after_update回调调用它来调用它

bet.rb

中的

# class method that settles the given bet
def self.settle(bet)
  message = nil
  if not bet.choice.spotprice.nil?
    case 
    when bet.choice.spotprice.value > bet.choice.value && bet.buy == true
      profitloss  = 10
      message =  "#{bet.id}: Win (1)"
    when bet.choice.spotprice.value < bet.choice.value && bet.buy == false 
      profitloss  = 10
      message =  "#{bet.id}: Win (2)"
    when bet.choice.spotprice.value > bet.choice.value && bet.buy == false
      profitloss  = -10
      message =  "#{bet.id}: Lose (3)"
    when bet.choice.spotprice.value < bet.choice.value && bet.buy == true 
      profitloss  = -10
      message =  "#{bet.id}: Lose (4)"
    when bet.choice.spotprice.value == bet.choice.value
      profitloss  = -10
      message =  "#{bet.id}: Lose (5)"
    end

    if profitloss  
      bet.settled    = true
      bet.profitloss = profitloss 
      bet.save
    end 
  end

  if bet.choice.settled == true
    bet.choice.settled = false
    bet.choice.save
  end
  # return message
  message
end
spot_price.rb

中的

class SpotPrice
  after_update Bet.settle(self)
  after_save   Bet.settle(self)

  ....
end

这不会处理Pusher的其他输出(在message变量中保存并返回)。此外,无法帮助自己,但我认为你的意思是“失去”,而不是“松散”。

这是你要找的吗?