在ruby中重构出常见的方法参数



我有一个带有如下方法的mailer:

def review_comment_notification comment_id, locale = I18n.locale
    comment = Spree::Comment.find(comment_id)
    assign(:review, review_data(comment.commentable))
    assign(:user, user_data(comment.commentable.user))
    assign(:commenter, user_data(comment.user))
    assign(:unsubscribe, unsubscribe_data(self.action))
    assign(:comment, comment_data(comment))
    mail(
      email_id: REVIEW_COMMENT_NOTIFICATION_TEMPLATE,
      recipient_address: comment.commentable.user.email,
      version_name: localized_version(locale)
    )
  end
  def store_credit_receipt(user_id, store_credit_id, locale = I18n.locale)
    store_credit = Spree::StoreCredit.find(store_credit_id)
    user = Spree::User.find(user_id)
    assign(:user, user_data(user))
    assign(:store_credit, store_credit_data(store_credit))
    assign(:unsubscribe, unsubscribe_data(self.action))
    mail(
      email_id: STORE_CREDIT_RECEIPT_TEMPLATE,
      recipient_address: user.email,
      version_name: localized_version(locale)
    )
  end
  def reset_password_instructions user, store_id, locale = I18n.locale
    # Dual handling here kept due to external libraries.
    user = user.respond_to?(:id) ? user : Spree::User.find(user)
    set_store(Spree::Store.find(store_id)) if store_id
    password_reset_url = spree.edit_password_url(
      reset_password_token: user.reset_password_token
    )
    assign(:password_reset_url, password_reset_url)
    mail(
      email_id: RESET_PASSWORD_INSTRUCTIONS_TEMPLATE,
      recipient_address: user.email,
      version_name: localized_version(locale)
    )
  end
  def welcome user_id, store_id, locale = I18n.locale
    user = Spree::User.find(user_id)
    set_store(Spree::Store.find(store_id)) if store_id
    assign(:user, user_data(user))
    mail(
      email_id: WELCOME_TEMPLATE,
      recipient_address: user.email,
      version_name: localized_version(locale)
    )
  end

现在,我们需要运行时的当前区域设置来决定发送哪个版本的电子邮件。还要注意,这不是一个标准的ActionMailer邮件程序。

问题是,为了实现这一点,我必须将locale=I18n.locale添加到我们所有邮件程序的每个方法中。

这对我来说是一个很大的气味。但因为我在方法调用时需要区域设置,所以我不能将其作为类默认值(除非我遗漏了什么)

有没有办法重构这个添加的逻辑?

这些都是实例方法,对吧?当一个对象到处都需要数据时,做什么就做什么,在构建过程中传递数据:

mailer = WhateverMailer.new(locale: I18n.locale)
mailer.welcome(user_id, store_id)

因此,您只需将区域设置作为实例变量存储在您的mailer中。看看其余的方法,这个模式似乎可以帮助清理user_id之类的其他东西。

最新更新