0

この Railscast http://railscasts.com/episodes/127-rake-in-background?autoplay=trueを例/インスピレーションとして使用します (つまり、レールキャストコードを実装しようとしているのではなく、インスピレーションとして使用してください) 、user.rbモデルのafter_createコールバックによってトリガーされたメーラーをrakeタスクに移動しようとしたため、バックグラウンドで実行されました。rake タスクに移動する前は、メーラーは機能していましたが、機能しなくなりました。

User.rb モデルからメーラーを呼び出すのではなく (user.rb のコメントアウトされたコードを参照)、代わりに rake タスクを呼び出します。これにより、UserMailer.welcome_email メソッドが呼び出されます。

元のコードでは、「self」が (User.rb から) パラメータとしてwelcome_email(user)user_mailer.rb のメソッドに送信されました。これを rake タスクに変えようとして、「self」を USER_INSTANCE に割り当てました。これは、mailer.rake で ENV["USER_INSTANCE"] として取得されるはずです。これは、Railscast によっても提案されました。

途中でうまくいかないところがあります。何か案は?

ユーザー.rb

 after_create :send_welcome_email



  def send_welcome_email
    system "rake :send_mailing USER_INSTANCE=self &"   #note the & forks the task
    #UserMailer.welcome_email(self).deliver  <-- how it was originally. 
  end

mailer.rake

desc "Send mailing"
task :send_mailing => :environment do

 UserMailer.welcome_email(ENV["USER_INSTANCE"]).deliver  #moved from user.rb to here but now with environment variable instead of parameter
end

変更されていない User_mailer.rb

 class UserMailer < ActionMailer::Base
  default :from => "blahblah@gmail.com"

  def welcome_email(user)
    mail(:to => user.email, :subject => "Invitation Request Received")
  end

終わり

4

1 に答える 1

1

現在、あなたはこれを行っています

system "rake :send_mailing USER_INSTANCE=self &"

これは、コマンドラインに移動して入力するのと同じです

rake :send_mailing USER_INSTANCE=self &

self は単なるリテラル文字列です。あなたがやろうとしていることはこれだと思います

system "rake :send_mailing USER_INSTANCE=#{self} &"

しかし、それはコマンドラインでこれを実行するのと同等になります

rake :send_mailing USER_INSTANCE=<User::xxxxx>

rake はこれを User ActiveRecord オブジェクトにシリアライズしません。システムでシェルアウトする場合、呼び出し元のコードとは関係ありません

別の方法 - rake タスクは整数を取って user_id を取得し、User.find を介してレコードにアクセスできますが、 after_create がトランザクションで実行されるため、より複雑になります。取引

レールでバックグラウンド処理を行う方法を再発明しようとしないことをお勧めします。すでに優れた実証済みの真のソリューションが利用可能です

一部のオプションについては、 http://railscasts.com/?tag_id=32を参照してください

于 2012-05-12T20:57:34.200 に答える