module JamRuby class EmailBatch < ActiveRecord::Base self.table_name = "email_batches" attr_accessible :from_email, :subject, :test_emails, :body attr_accessible :lock_version, :qualified_count, :sent_count, :started_at, :completed_at VAR_FIRST_NAME = '@FIRSTNAME' VAR_LAST_NAME = '@LASTNAME' DEFAULT_SENDER = "support@jamkazam.com" include AASM aasm do state :pending, :initial => true state :testing state :tested state :batching state :batched state :disabled event :enable do transitions :from => :disabled, :to => :pending end event :reset do transitions :from => [:disabled, :testing, :tested, :batching, :batched, :pending], :to => :pending end event :do_test_run, :before => :running_tests do transitions :from => [:pending, :tested, :batched], :to => :testing end event :did_test_run, :after => :ran_tests do transitions :from => :testing, :to => :tested end event :do_batch_run, :before => :running_batch do transitions :from => [:tested, :pending, :batched], :to => :batching end event :did_batch_run, :after => :ran_batch do transitions :from => :batching, :to => :batched end event :disable do transitions :from => [:pending, :tested, :batched], :to => :disabled end end # has_many :email_batch_results, :class_name => 'JamRuby::EmailBatchResult' def self.create_with_params(params) obj = self.new obj.update_with_params(params) obj.save! obj end def update_with_params(params) self.from_email = params[:from_email].strip self.subject = params[:subject].strip self.test_emails = params[:test_emails].strip self.body = params[:body].strip self end def deliver_batch self.perform_event('do_batch_run!') User.email_opt_in.pluck(:id).find_in_batches(batch_size: 1000) do |user_ids| BatchMailer.send_batch_email(self.id, user_ids).deliver end end def test_count self.test_emails.split(',').count end def test_users self.test_emails.split(',').collect do |ee| ee.strip! uu = User.new uu.email = ee uu.first_name = ee.match(/^(.*)@/)[1].to_s uu.last_name = 'Test' uu end end def send_test_batch self.perform_event('do_test_run!') BatchMailer.send_batch_email_test(self.id).deliver end def merged_body(user) body.gsub(VAR_FIRST_NAME, user.first_name).gsub(VAR_LAST_NAME, user.last_name) end def did_send(emails) self.update_with_conflict_validation({ :sent_count => self.sent_count + emails.size }) if self.sent_count >= self.qualified_count if batching? self.perform_event('did_batch_run!') elsif testing? self.perform_event('did_test_run!') end end end def perform_event(event_name) num_try = 0 self.send(event_name) rescue ActiveRecord::StaleObjectError num_try += 1 if 5 > num_try self.reload retry end end def update_with_conflict_validation(*args) num_try = 0 update_attributes(*args) rescue ActiveRecord::StaleObjectError num_try += 1 if 5 > num_try self.reload retry end end def running_batch self.update_with_conflict_validation({:qualified_count => User.email_opt_in.count, :sent_count => 0, :started_at => Time.now }) end def running_tests self.update_with_conflict_validation({:qualified_count => self.test_count, :sent_count => 0, :started_at => Time.now }) end def ran_tests self.update_with_conflict_validation({ :completed_at => Time.now }) end def ran_batch self.update_with_conflict_validation({ :completed_at => Time.now }) end end end