Frage

There are several stages to this, and as I am relatively new to rails I am unsure if I am approaching this in the best way.

Users follow Firms, Firms applications open and close on certain days. If a user follows a firm I would like them to automatically get an email when a) the firms application opens, b) a week before the firms applications close, c) on the day that the firms applications close.

I have tried using named scope. I have the following model method (I presume this will need a little work) setting each firms scope, depending on the date.

model firms.rb

   def application_status
     if open_date == Today.date
      self.opening = true
     else
      self.opening = false
     end 

    if ((close_day - Today.date) == 7)
     self.warning = true
      else
     self.warning = false
    end 

    if close_day == Today.date
     self.closing = true
      else
     self.closing = false
    end 
 end

I would like this method to be called on each firm once a day, so that each firm has the appropriate scope - so I have tried using the whenever gem (cron) and the following code. Running the above model method on each firm.

Schedule.rb

every 1.day do 
 runner "Firm.all.each do |firm|
  firm.application_status
 end"
end

Then for each of the scopes opening, warning, closing i have a method in the whenever schedules file, For simplicity I shall show just the opening methods. The following queries for all firms that have had the opening scope applied to them, and runs the application_open_notification method on them.

Schedule.rb

every 1.day do
 runner "Firm.opening.each do |firm|
  firm.application_open_notification
 end"
end

This calls the following method in the Firm.rb model

def application_open_notification
  self.users.each do |user|
   FirmMailer.application_open(user, self).deliver
  end
end

Which in turn calls the final piece of the puzzle... which should send the user an email, including the name of the firm.

def application_open(user,firm)
  @firm = firm
  @user = user
    mail to: @user.email, subject: @firm' is now accepting applications'
  end
 end

Is this a viable way to approach this problem? In particular I am not very familiar with coding in the model.

Many thanks for any help that you can offer.

War es hilfreich?

Lösung

I'll guess that opening, warning and closing are database fields, and you have scopes like:

class Firm < ActiveRecord::Base
    scope :opening, :where => { :opening => true }
    # etc
end

There is a general rule for database (and, well, all storage): don't store things you can caculate, if you don't have to.

Since an application's status can be dermined from the day's date and the open_date and close_day fields, you could calculate them as needed instead of creating extra fields for them. You can do this with SQL and Active Record:

scope :opening, :where { :open_date => (Date.today .. Date.today+1) }
scope :warning, :where { :close_day => (Date.today+7 .. Date.today+8) }
scope :closing, :where { :close_day => (Date.today .. Date.today+1) }

(Note that these select time ranges. They may have to be changed depending on if you are using date or time fields.)

But there is another issue: what happens if, for some reason (computer crash, code bug etc) your scheduled program doesn't run on a particular day? You need a way of making sure notices are sent eventually even if something breaks. There are two solutions:

  1. Write your schedule program to optionally accept a date besides today (via ARGV)
  2. keep flags for each firm for whether each kind of notice has been sent. These will have to be stored in the databse.

Note that scopes aren't necessary. You are able to do this:

Firm.where(:open_date => (Date.today .. Date.today+1)).each do |firm|
   #...
end

but the scope at least encapsulates the details of identifying the various sets of records.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top