Gemを追加します。
gem 'delayed_job'
gem 'delayed_job_active_record'
gem 'daemons'
選び方などは省略するとして、モデルでdeliverを作成します。gem 'delayed_job_active_record'
gem 'daemons'
has_many :destinations, through: :parcels, class_name: "User"
def destination_id_map=(hash)
hash.each do |user_id, value|
c = User.find_by_id(user_id)
self.destinations << c
end
end
LIMIT = 100
def deliver
return unless status == "wating"
log_dir = Rails.root.join('log', 'messages')
Dir.mkdir(log_dir) unless File.exist?(log_dir)
filename = sprintf('%06d.log', id)
logger = Logger.new(Rails.root.join('log', 'messages', filename))
logger.info('started. ' + Time.current.to_s(:db))
current_parcels_id = nil
loop do
parcels = self.parcels.order('parcels.destination_id ASC').limit(LIMIT).includes(:destination)
parcels = parcels.where('parcels.id > ?', current_parcels_id) if current_parcel_id
parcels.each do |parcel|
next if parcel.destination.deleted?
begin
UserMailer.notice(parcel).deliver
parcel.update_attribute(:status, "sent")
logger.info(sprintf("06d ok %s %s", parcel.destination_id, parcel.destination_mail))
rescue Exception => e
raise e if Rails.env.test?
parcel.update_attribute(:status "error")
logger.info(sprintf("%06d NG %s %s", parcel.destination_id, parcel.destination_mail e.to_s))
end
end
break if parcels.size < LIMIT
current_parcel_id = parcels.last.id
end
update_attribute(:status, "sent")
logger.info('Ended. ' + Time.current.to_s(:db))
end
mailer/user_mailer.rbを作成します
def destination_id_map=(hash)
hash.each do |user_id, value|
c = User.find_by_id(user_id)
self.destinations << c
end
end
LIMIT = 100
def deliver
return unless status == "wating"
log_dir = Rails.root.join('log', 'messages')
Dir.mkdir(log_dir) unless File.exist?(log_dir)
filename = sprintf('%06d.log', id)
logger = Logger.new(Rails.root.join('log', 'messages', filename))
logger.info('started. ' + Time.current.to_s(:db))
current_parcels_id = nil
loop do
parcels = self.parcels.order('parcels.destination_id ASC').limit(LIMIT).includes(:destination)
parcels = parcels.where('parcels.id > ?', current_parcels_id) if current_parcel_id
parcels.each do |parcel|
next if parcel.destination.deleted?
begin
UserMailer.notice(parcel).deliver
parcel.update_attribute(:status, "sent")
logger.info(sprintf("06d ok %s %s", parcel.destination_id, parcel.destination_mail))
rescue Exception => e
raise e if Rails.env.test?
parcel.update_attribute(:status "error")
logger.info(sprintf("%06d NG %s %s", parcel.destination_id, parcel.destination_mail e.to_s))
end
end
break if parcels.size < LIMIT
current_parcel_id = parcels.last.id
end
update_attribute(:status, "sent")
logger.info('Ended. ' + Time.current.to_s(:db))
end
class UserMailer < ActionMailer::Base
default from: "from@example.com"
def notice(parcel)
mail(
:subject => parcel.message.subject,
:from => parcel.message.from,
:to => parcel.destination.mail
)
end
end
controllerのcreateで作成して完了です。
default from: "from@example.com"
def notice(parcel)
mail(
:subject => parcel.message.subject,
:from => parcel.message.from,
:to => parcel.destination.mail
)
end
end
def create
@message = Message.new(params[:message])
if params[:destinations].kind_of?(Hash)
@message.destination_id_map = params[:destinations]
@message.save!
@message.delay.deliver
redirect_to action: :index
end
end
delayed_jobは使い方を学ぶ必要があります。Google先生に聞いて下さい。
@message = Message.new(params[:message])
if params[:destinations].kind_of?(Hash)
@message.destination_id_map = params[:destinations]
@message.save!
@message.delay.deliver
redirect_to action: :index
end
end