将多个对象传递到 mailer/email 内容 rails 中

Pass multiple objects into action mailer/email contents in rails

想了解如何将多个对象传递到 rails 中的操作 mailer/email 内容中。我在传递@announcement 时没有问题,但不确定如何传递@post 和@user 信息。

announcement_controllers.rb
  def create
    @post = Post.find_by slug: params[:post_id]
    @announcement = @post.announcements.build(announcement_params)
    @announcement.creator = current_user
    if @announcement.save
      flash[:notice] = 'Your announcement was created.'      
      AnnouncementMailer.announcement_alert(@announcement, @post).deliver
      redirect_to :back
    else
      flash[:notice] = 'Unable to create announcement. Make sure you have enter information.'
      redirect_to :back      
    end
  end

announcement_mailer.rb
class AnnouncementMailer < ActionMailer::Base
  binding.pry
  default to: Proc.new { Signup.where(post_id: @post.id, user_id: current_user.id).pluck(:email) }, 
          from: "#{@post.slug}@fundspace.announcement.com"

  def announcement_alert(announcement, post)
    @announcement = announcement
    @post = post    
    mail(subject: "#{@post.slug}: #{@announcement.title}")
  end

end

binding.pry
    1: class AnnouncementMailer < ActionMailer::Base
 => 2:   binding.pry
    3:   default to: Proc.new { Signup.where(post_id: @post.id, user_id: current_user.id).pluck(:email) }, 
    4:           from: "#{@post.slug}@fundspace.announcement.com"
    5: 
    6:   def announcement_alert(announcement, post)
    7:     @announcement = announcement

[1] pry(AnnouncementMailer)> @post
=> nil
[2] pry(AnnouncementMailer)> @announcement
=> nil
[3] pry(AnnouncementMailer)> @user
=> nil

binding.pry 检查@post in announcement_mailer.rb returns nil。不知道为什么。提前致谢。

这是您的调试代码的 classic 案例,给您留下了错误的印象。您的 @post 顺利通过 - 但它发生在 调用 binding.pry 之后。

您将 post 传递给 announcement_alert,这会将其设置为实例变量。如果您将该方法更新为如下所示,您应该会看到它设置良好:

def announcement_alert(announcement, post)
  @announcement = announcement
  @post = post
  binding.pry    
  mail(subject: "#{@post.slug}: #{@announcement.title}")
end

(您没有检查 post 是您的邮件程序中的一个对象,因此其他代码可能会通过 nil。不过在这种情况下这应该不是问题- 如果没有匹配项,Post.find_by 将 return nil,但如果有匹配项,您的 @post.announcements.build 将失败。)


这种对 @post 设置位置的混淆也会导致 default 行出现问题。方法外的语句——比如你的binding.pry和你的default to:——当class被评估时得到运行。方法内的语句 - def announcement_alert 内的语句 - 在调用该方法之前不要 运行。而且,正如我们在上面看到的,直到您调用 announcement_method 才定义 @post

这是您当前的 default 声明:

default to: Proc.new { Signup.where(post_id: @post.id, user_id: current_user.id).pluck(:email) }, 
        from: "#{@post.slug}@fundspace.announcement.com"

您的 to: 参数设置为 Proc,这很好 - 即使它引用 @post,因为它是 Proc 而不是 运行 直到需要它为止。届时您将设置 @post

另一方面,您的 from: 参数只是一个字符串。它在过程之外。因此,它会尝试立即评估 @post.slug - 但尚未设置 @post,从而导致错误。将其更改为此修复它:

default to: Proc.new { Signup.where(post_id: @post.id, user_id: current_user.id).pluck(:email) }, 
        from: Proc.new { "#{@post.slug}@fundspace.announcement.com" }