Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing rails flash[:notice] in a model

I am trying to assign a message to flash[:notice] in a model observer.

This question has already been asked: Ruby on Rails: Observers and flash[:notice] messages?

However, I get the following error message when I try to access it in my model:

undefined local variable or method `flash' for #<ModelObserver:0x2c1742c>

Here is my code:

class ModelObserver < ActiveRecord::Observer
  observe A, B, C

  def after_save(model)
    puts "Model saved"
    flash[:notice] = "Model saved"
  end
end

I know the method is being called because "Model saved" is printed to the terminal.

Is it possible to access the flash inside an observer, and if so, how?

like image 715
titaniumdecoy Avatar asked Apr 23 '10 20:04

titaniumdecoy


2 Answers

I needed to set flash[:notice] in the model to override the generic "@model was successfully updated".

This what I did

  1. Created a virtual attribute in the respective model called validation_message
  2. Then I set the virtual attribute in the respective model when needed
  3. Used an after_action when this virtual attribute was not blank to override the default flash

You can see my controller and model how I accomplished this below:

class Reservation < ActiveRecord::Base

  belongs_to :retailer
  belongs_to :sharedorder
  accepts_nested_attributes_for :sharedorder
  accepts_nested_attributes_for :retailer

  attr_accessor :validation_code, :validation_messages

  validate :first_reservation, :if => :new_record_and_unvalidated

  def new_record_and_unvalidated
    if !self.new_record? && !self.retailer.validated?
      true
    else
      false
    end
  end

  def first_reservation
    if self.validation_code != "test" || self.validation_code.blank?
      errors.add_to_base("Validation code was incorrect") 
    else
      self.retailer.update_attribute(:validated, true)
      self.validation_message = "Your validation is successful and you will not need to do that again"
    end
  end
end

class ReservationsController < ApplicationController

  before_filter :authenticate_retailer!
  after_filter :validation_messages, :except => :index

  def validation_messages
    return unless @reservation.validation_message.present?

    flash[:notice] = @reservation.validation_message
  end
end

One possible refactor would be to move the actual message in a proper file (e.g. a locale) and pass to validation_message only the proper key.

Should you need more than one notice it's easy enough to turn validation_message into an array or a hash and call it validation_messages instead.

like image 152
thenengah Avatar answered Sep 22 '22 17:09

thenengah


No, you set it in the controller where the saving is occurring. flash is a method defined on ActionController::Base.

like image 21
Ryan Bigg Avatar answered Sep 21 '22 17:09

Ryan Bigg