ruby on rails - How to call ActionMailer method in aasm callback? -


im learning ruby on rails , have trouble aasm callbacks , actionmailer. have hotels model. heres code:

class hotel < activerecord::base   include aasm    scope :approved_hotels, -> { where(aasm_state: "approved") }    has_many :comments     belongs_to :user, :counter_cache => true     has_many :ratings   belongs_to :address    aasm     state :pending, initial: true     state :approved     state :rejected      event :approve, :after => :send_email       transitions from: :pending, to: :approved      end     event :reject, :after => :send_email       transitions from: :pending, to: :rejected     end   end    def send_email    end end 

as see user has email when state of hotel added changed. heres wrote not solution cos user gets emails every time admin updates hotel "pending" state.

class hotelscontroller < applicationcontroller   before_filter :authenticate_user!, except: [:index, :show, :top5hotels]    def update     @hotel = hotel.find(params[:id])      if @hotel.aasm_state == "pending"       @hotel.aasm_state = params[:state]       usermailer.changed_state_email(current_user, @hotel.name,        @hotel.aasm_state).deliver     end      if @hotel.update_attributes!(params[:hotel])       redirect_to admin_hotel_path(@hotel), notice: "hotel updated."     else       render "edit"     end   end end 

so think need use callback dont know how call

usermailer.changed_state_email(current_user, @hotel.name,          @hotel.aasm_state).deliver 

from model. tried

usermailer.changed_state_email(user.find(:id), hotel.find(:name),          hotel.find(aasm_state)).deliver 

but doesnt work. im out of options , looking help. thanks!

you can't use callback because have current_user part of controller context, , can't access request information in model context.

anyway, if use callback, in case encourage follow different path. activerecord callbacks should used, in particular should avoid them code involves interaction other objects or resources such mailers or cascade update. risk callback triggered when don't need (e.g. tests) increasing overhead, or conflict other callbacks when complexity of project increase.

in case solution simple. define new method in model (i'm not introducing service objects now...) use change state , deliver email.

class hotel   def user_state_change(user, new_state)     return unless pending? && new_state.present?      if update_attribute(:aasm_state, new_state)       usermailer.changed_state_email(user, name, aasm_state).deliver     end   end end 

your controller become

class hotelscontroller < applicationcontroller   before_filter :authenticate_user!, except: [:index, :show, :top5hotels]    def update     @hotel = hotel.find(params[:id])     @hotel.user_state_change(current_user, params[:state])      if @hotel.update_attributes!(params[:hotel])       redirect_to admin_hotel_path(@hotel), notice: "hotel updated."     else       render "edit"     end   end end 

as side note, may want use state machine transition methods, rather changing state attribute. in fact, using state machine transition ensure transition validation triggered.


Comments

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -