Программа рассылки действий Rails и возвращает статус 200, если электронное письмо было отправлено

#ruby-on-rails #ruby #ruby-on-rails-5 #actionmailer

#ruby-on-rails #ruby #ruby-on-rails-5 #actionmailer

Вопрос:

У меня есть Rails API со следующей почтовой программой:

   def demo_request
    @user = params[:user]

    mail(
        to: "foo@bar.com",
        subject: "[DEMO REQUEST] #{@user[:name]} - #{@user[:email]}",
        body: "A potential customer, #{@user[:name]}, requested a demo be sent to them. You can follow up with them at #{@user[:email]}",
        content_type: "text/html"
    )
  end
  

Очень простой, он запускается следующим контроллером:

   class DemoRequestsController < ApplicationController
    skip_before_action :authenticate_user!

    def create
      @user = params.permit(:email, :name)
      UserMailer.with(user: @user).demo_request.deliver_now
    end
  end
  

Также очень просто, он просто вызывает почтовую программу при получении запроса POST с некоторыми параметрами. Этот API используется клиентским приложением, формы Rails здесь не играют роли.

При тестировании я вижу, что программа рассылки, похоже, работает нормально, но проблема в том, что, очевидно, контроллер вернет 204: No Content ответ.

Каков правильный способ заставить контроллер вернуть 200 OK ответ, только если программа рассылки прошла успешно? В противном случае верните 404 или сообщение об ошибке или что-то еще подходящее.

Ответ №1:

Простого head :ok может быть достаточно.

 def create
  @user = params.permit(:email, :name)
  UserMailer.with(user: @user).demo_request.deliver_now
  head :ok
end
  

Потому что, если отправка электронного письма завершится неудачно, тогда все 500 ServerError равно будет.

Ответ №2:

Неясно, вызывается ли ваш контроллер из клиентского приложения (вы обрабатываете его как JSON api) или это простые формы rails.

Если api / сервис json, вы можете попытаться вернуть json обратно

 begin
  UsererMailer.with(user: @user).demo_request.deliver_now
  render json: { message: 'ok' }, status: 200
rescue StandardError => e
  render json: { error: e.inspect }, status: 500
end

  

Если это обычный контроллер / приложение Rails, я бы предложил просто перенаправить пользователя куда-нибудь:

 begin
  UsererMailer.with(user: @user).demo_request.deliver_now
  redirect_to some_path
rescue StandardError => e
  redirect_to some_path, error: e.inspect
end