aasm gem和ActionMailer

时间:2015-05-28 23:36:15

标签: ruby-on-rails ruby callback actionmailer aasm

我在轨道上学习ruby并且在aasm回调和动作管理器方面遇到麻烦。 我有酒店模特。下面是代码:

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 do
    state :pending, initial: true
    state :approved
    state :rejected

    event :approve, :after => :send_email do
      transitions from: :pending, to: :approved 
    end
    event :reject, :after => :send_email do
      transitions from: :pending, to: :rejected
    end
  end

  def send_email

  end
end

如您所见,当他添加的酒店状态发生变化时,用户必须收到电子邮件。下面是我写的但不是解决方案cos用户每次管理员更新酒店时都会收到电子邮件&#34;待定&#34;状态。

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 was successfully updated."
    else
      render "edit"
    end
  end
end

所以我认为我需要使用回调,但我不知道如何调用

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

来自模特。 我试过了

UserMailer.changed_state_email(User.find(:id), Hotel.find(:name), 
        Hotel.find(aasm_state)).deliver

但这不起作用。  我真的没有选择,并寻求任何帮助。 谢谢!

更新1: 感谢Amit Sharma!我做了这些改变,现在得到了

NoMethodError: undefined method `email' for nil:NilClass

看起来我传递给changed_state_email()方法的用户对象是nill,但我不知道为什么。 这是我的邮件文件以及:

class UserMailer < ActionMailer::Base
  default from: "localhost"

  # Send email to user when hotels state change
  def changed_state_email(user, hotel_name, current_state)
    mail(to: user.email, subject: 'State of your hotel  '+hotel_name+'has been 
        changed to  '+current_state)
  end
end

这是put&#34; ====#{self.inspect}&#34;的结果:

====#<Hotel id: nil, name: "CoolName", breakfast: nil, room_description: nil, price_for_room: 34, star_rating: 3, user_id: nil, address_id: nil, created_at: nil, updated_at: nil, average_rating: nil, photo_file_name: nil, photo_content_type: nil, photo_file_size: nil, photo_updated_at: nil, aasm_state: "approved">

F。====# F。====#

更新2: 它返回用户对象。控制台输出:

1.9.3-p551 :006 > h = Hotel.find(1)
  Hotel Load (0.4ms)  SELECT "hotels".* FROM "hotels" WHERE "hotels"."id" = ? LIMIT 1  [["id", 1]]
 => #<Hotel id: 1, name: "QWERTYUI", breakfast: nil, room_description: nil, price_for_room: 44, star_rating: 4, user_id: 2, address_id: nil, created_at: "2015-05-30 22:55:01", updated_at: "2015-05-30 22:55:01", average_rating: nil, photo_file_name: nil, photo_content_type: nil, photo_file_size: nil, photo_updated_at: nil, aasm_state: "pending"> 
1.9.3-p551 :007 > h
 => #<Hotel id: 1, name: "QWERTYUI", breakfast: nil, room_description: nil, price_for_room: 44, star_rating: 4, user_id: 2, address_id: nil, created_at: "2015-05-30 22:55:01", updated_at: "2015-05-30 22:55:01", average_rating: nil, photo_file_name: nil, photo_content_type: nil, photo_file_size: nil, photo_updated_at: nil, aasm_state: "pending"> 
1.9.3-p551 :008 > h.user
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 2]]
 => #<User id: 2, name: "qwerty", email: "qweqweqweqwe@qwe.com", encrypted_password: "$2a$10$FG5xXb/9wYLcdsCrfJtuDOTsslyY8p.m0qkbP4a5OEvJ...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, admin: false, created_at: "2015-05-30 22:54:14", updated_at: "2015-05-30 22:54:14", comments_count: 0, hotels_count: 1>

1 个答案:

答案 0 :(得分:0)

你可以试试这个。我希望这会对你有所帮助。

酒店控制器

class HotelsController < ApplicationController
  before_filter :authenticate_user!, except: [:index, :show, :top5hotels]

  def update
    @hotel = Hotel.find(params[:id])

    if @hotel.pending?
      if params[:state] == "approved"
        @hotel.approved!
      elsif params[:state] == "rejected"
        @hotel.rejected!
      end
   end

    if @hotel.update_attributes!(params[:hotel])
      redirect_to admin_hotel_path(@hotel), notice: "Hotel was successfully updated."
    else
      render "edit"
    end
  end
end

酒店模型中。

def send_email
  user = self.user
  puts "====#{self.inspect}===#{user.inspect}"
  UserMailer.changed_state_email(user, self.name, 
  self.aasm_state).deliver
end

如果您遇到任何问题,请回复我。