Accessing rails flash[:notice] in a model
I am trying to assign a message to flash[:notice] in a mo开发者_开发问答del 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?
No, you set it in the controller where the saving is occurring. flash
is a method defined on ActionController::Base
.
I needed to set flash[:notice]
in the model to override the generic "@model was successfully updated".
This what I did
- Created a virtual attribute in the respective model called
validation_message
- Then I set the virtual attribute in the respective model when needed
- 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.
精彩评论