1

ActionMailer::Base provides call backs like ActionController::Base does which allows for common code to be called before a mailer function/action. It seems this is not supported for ActionMailer::Preview classes but could be useful. Is there a module I can include that would give me this functionality so I can call something like:

class MailerPreview < ActionMailer::Preview
  include SomeCallBackModule

  before_action :create_records

  def mailer_a
    # Don't need this anymore because create_records gets called
    # @user = FactoryBot.create(:some_factory)
    # @widget = FactoryBot.create(:another_factory, user: @user)
    Mailer.mailer_a(@user, @widget)
  end

  def mailer_b
    # Don't need this anymore because create_records gets called
    # @user = FactoryBot.create(:some_factory)
    # @widget = FactoryBot.create(:another_factory, user: @user)
    Mailer.mailer_b(@user, @widget)
  def

  private

  def create_records
    @user = FactoryBot.create(:some_factory)
    @widget = FactoryBot.create(:another_factory, user: @user)
  end
end
aarona
  • 35,986
  • 41
  • 138
  • 186
  • Yes and no. The callbacks for ActionMailer are handled by `AbstractController::Callbacks` but that requries you to wrap the method invocation so that it fires the callbacks. There is also a generic implementation of Callbacks provided by `ActiveSupport::Callbacks`. But @spickermann's suggestion is a much simpler solution to the problem. – max Feb 16 '23 at 12:59
  • See https://api.rubyonrails.org/classes/AbstractController/Callbacks.html – max Feb 16 '23 at 13:02

1 Answers1

0

ActionMailer::Preview indeed doesn't support callbacks out of the box.

In your example, I would suggest calling a simple private method directly instead of with a callback:

class MailerPreview < ActionMailer::Preview
  def mailer_a
    Mailer.mailer_a(user)
  end

  def mailer_b
    Mailer.mailer_b(user)
  def

  private

  def user
    @user ||= User.first
  end
end
spickermann
  • 100,941
  • 9
  • 101
  • 131
  • My example is a simplified version of what I needed. Your example would work (and I do do this for this scenario.) – aarona Feb 16 '23 at 15:17
  • Then I suggest having a look at [`ActiveModel::Callbacks` module](https://github.com/rails/rails/blob/main/activemodel/lib/active_model/callbacks.rb) that provides an interface for any class to have `ActiveRecord` like callbacks. – spickermann Feb 16 '23 at 15:31
  • Ok, I edited my question to better demonstrate what my situation is. I need to do more than just load a record. I provided an example using `FactoryBot` to create sample data to preview the mailer. – aarona Feb 16 '23 at 16:53