Ruby on rails 3.2 继承资源:如何在创建或更新操作后发送电子邮件

Ruby on rails 3.2 继承资源:如何在创建或更新操作后发送电子邮件,ruby-on-rails-3.2,actionmailer,inherited-resources,Ruby On Rails 3.2,Actionmailer,Inherited Resources,我想知道在继承的资源框架中创建或更新记录时,发送电子邮件的最佳方式是什么 现在我正在这样做: def create create! UserMailer.create(object).deliver if @user.valid? end def update update! UserMailer.update(object).deliver if @user.valid? end 这是有道理的,但似乎有点笨重。我试着在成功响应块中这样做,但这

我想知道在继承的资源框架中创建或更新记录时,发送电子邮件的最佳方式是什么

现在我正在这样做:

  def create
    create!
    UserMailer.create(object).deliver if @user.valid?
  end

  def update
    update!
    UserMailer.update(object).deliver if @user.valid?
  end
这是有道理的,但似乎有点笨重。我试着在成功响应块中这样做,但这似乎也是一件坏事。我还尝试链接到update_资源和create_资源方法。它们都能工作,但看起来都不太优雅


也许我是想尽量减少代码太多

我更喜欢这种方法:

def create
  if @user.save # if your user is saved it should be valid
    do something
  else
    do something else
  end
end

def update
  if @user.update_attributes(params[:user])
    do something
  else
    do something else
  end
end

您可以重构电子邮件的发送,并使用after过滤器。在这种情况下,可以删除create和update,除非修改它们的默认行为。未经测试,但这是一个想法:

after_filter :send_email, :only => [ :create, :update ]

private
def send_email
  UserMailer.send(request[:action].to_sym, @user).deliver if @user.valid?
end

我更喜欢DDD方法,使用

因此,如果您想在每次保存型号后发送电子邮件,您应该这样做

class Example < ActiveRecord::Base
  after_save :send_email

  protected
  def send_email
    UserMailer.create(object).deliver
  end
end
类示例
以下是我目前正在做的事情。对我来说,这是最好的、不那么混乱的方法:

  after_filter :send_create_email, :only => :create
  after_filter :send_update_email, :only => [:update, :update_password]

  private

  def send_create_email
    UserMailer.create(@user).deliver if @user.valid?
  end

  def send_update_email
    UserMailer.update(@user).deliver if @user.valid?
  end
  # Responsible for saving the resource on :create method. Overwriting this
  # allow you to control the way resource is saved. Let's say you have a
  # PassworsController who is responsible for finding an user by email and
  # sent password instructions for him. Instead of overwriting the entire
  # :create method, you could do something:
  #
  #   def create_resource(object)
  #     object.send_instructions_by_email
  #   end
  #
  def create_resource(object)
    object.save
  end

在我需要非标准方法名称之前,Nathans方法一直很好。

我认为覆盖
create\u resource
是一种很好的方法:

  after_filter :send_create_email, :only => :create
  after_filter :send_update_email, :only => [:update, :update_password]

  private

  def send_create_email
    UserMailer.create(@user).deliver if @user.valid?
  end

  def send_update_email
    UserMailer.update(@user).deliver if @user.valid?
  end
  # Responsible for saving the resource on :create method. Overwriting this
  # allow you to control the way resource is saved. Let's say you have a
  # PassworsController who is responsible for finding an user by email and
  # sent password instructions for him. Instead of overwriting the entire
  # :create method, you could do something:
  #
  #   def create_resource(object)
  #     object.send_instructions_by_email
  #   end
  #
  def create_resource(object)
    object.save
  end
它可以是这样的:

  ActiveAdmin.register SomeModel do
    controller do
      def create_resource(object)
        # TODO
      end
    end
  end

谢谢你。不幸的是,我不能接受这个答案,因为它没有专门处理继承的资源。这似乎是显而易见的方法,直到有必要在模型每次更改后都不发送电子邮件。经过深思熟虑,我确信最好是从控制器发送电子邮件(这使应用程序更灵活,测试更容易)。是的。此方法将在每次模型更新后发送电子邮件。但是,如果需要更改该行为,可以通过向send_email函数添加代码来完成(如果需要,可以检查模型变量)。如果您将功能放在控制器中,并且需要在应用程序的另一部分发送相同的电子邮件,则很可能您将重复代码,这是不好的。所以我不认为你的应用程序更灵活。关于测试,我认为这是一样的,你可以测试你的控制器或者模型,或者两者都可以。谢谢Paul,我认为这两种方法都有好处。在我的书中,不得不在应用程序中使用一行代码两三次并不算是重复。解决这个问题的另一种方法是使用一个抽象框架,如。它是否只是在控制器中?@BrendonMuir,是的。