Add a ship_date column to the orders table, and send a notification when this value is updated by the OrdersController.

Mark attempted:

Add ship_date (rails migrate add_ship_date_to_order)

class AddShipDateToOrder < ActiveRecord::Migration
  def self.up
    add_column :orders, :ship_date, :datetime
  end

  def self.down
    remove_column :orders, :ship_date   
  end
end

make it so rake db:migrate

Add Notifier call after updated, if ship_date set

  def update
    @order = Order.find(params[:id])

    respond_to do |format|
      if @order.update_attributes(params[:order])
        Notifier.order_shipped(@order).deliver unless @order.ship_date.nil?
        format.html { redirect_to(@order, :notice => 'Order was successfully updated.') }
        format.xml { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml { render :xml => @order.errors, :status => :unprocessable_entity }
      end
    end
  end

Note: This is a literal interpretation of the requirement. Seems it could be improved by make sure that not only is the ship_date no nil, but changed from before.

ok32 guessed:

I think it can be done this way:

 def update
  @order = Order.find(params[:id])
  @order.attributes = params[:order]

  ship_date_changed = @order.ship_date_changed?

  respond_to do |format|
    if @order.save
      OrderNotifier.shipped(@order).deliver if ship_date_changed

      format.html { redirect_to @order, :notice => 'Order was successfully updated.' }
      format.json { head :ok }
    else
      format.html { render :action => "edit" }
      format.json { render :json => @order.errors, :status => :unprocessable_entity }
    end
  end
end

Tom answered:

I managed to send an email when the shipping value had updated, however I wanted to extend beyond this and send a separate email if the shipping value was changed again.

I decided in the end it was best to perform all the actions within the model

Order.rb:

  after_update :send_new_ship_email, :if => :ship_date_changed? && :no_ship_date
  after_update :send_changed_ship_email, :if => :ship_date_changed? && :ship_date_was

  def no_ship_date
    self.ship_date_was.nil?
  end

  def send_new_ship_email
    Notifier.order_shipped(self).deliver
  end

  def send_changed_ship_email
    Notifier.changed_shipping(self).deliver
  end