Home > Mobile >  How to access current user in a mailer file before action
How to access current user in a mailer file before action

Time:09-16

I have a before action in a user mailer file, which is supposed to stop mailers sending if a column on user is set to true or false. However current user is currently unavailable. I understand why, but was wondering if there was a way to do this. I want to avoid adding the check_if_users_can_receive_mailers at the top of each mailer method.

  before_action :check_if_users_can_receive_mailers
  
  #methods that send mailers


  private 
  
  def check_if_users_can_receive_mailers
    current_user.send_mailers?
  end

CodePudding user response:

You have to make the current user available as a attribute or class variable. The most straight forward method is something like this:

class MailerBase < ActionMailer::Base
    before_action :check_if_users_can_receive_mailers
    attr_accessor :user
    
    def initialize(user)
        @user = user
    end
        
    private 
      
    def check_if_users_can_receive_mailers
        user.send_mailers?
    end
end

class SomeMailerClass < MailerBase

end

CodePudding user response:

In Rails only your controller and views are request aware. Mailers and models and other classes in your application are not and they cannot get the current user since they can't access the session nor the method current_user which is a helper method mixed into your controller (and the view context).

If your mailers need to know about the current user the most logical approach is to pass that information into the mailer:

class UserMailer < ApplicationMailer
  def intialize(user)
    @user = user
  end
end

However a mailer should only have one job - to send emails and it shouldn't be questioning if it should do the job or not. Determining if you should send an email to the user should be done elsewhere. You can place this logic in the controller or even better in a service object:

# app/notifiers/user_notifier.rb
class UserNotifier
  def initialize(user, event:)
    @user = user
    @event = event
  end

  def notify
    if @user.wants_email?
      spam_user! 
    end
    send_in_app_notification
  end

  def self.notify(user, event:)
     new(user, event:)
  end

  private

  def spam_user!
    # ...
  end

  def send_in_app_notification
    # ...
  end
end
class ThingsController
  def create
    @thing = Thing.new
    if @thing.save
      UserNotifier.notify(current_user, event: :thing_created)
      redirect_to @thing
    else
      render :new
    end 
  end
end
  • Related