在 ruby 中重构公共方法参数
Refactoring out common method arguments in ruby
我有一个邮件程序,其方法如下所示:
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 添加到我们所有邮件程序的每个方法中。
这对我来说是一种主要的气味。但是因为我在方法调用时需要语言环境,所以我不能将其设为 class 默认值(除非我遗漏了什么)
有没有办法重构这个添加的逻辑?
这些是实例方法,对吧?做一个对象到处需要数据时的做法,在构造时传入:
mailer = WhateverMailer.new(locale: I18n.locale)
mailer.welcome(user_id, store_id)
所以您只需将语言环境作为实例变量存储在您的邮件程序中。查看其余方法,似乎该模式可以帮助清理其他内容,例如 user_id
.
我有一个邮件程序,其方法如下所示:
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 添加到我们所有邮件程序的每个方法中。
这对我来说是一种主要的气味。但是因为我在方法调用时需要语言环境,所以我不能将其设为 class 默认值(除非我遗漏了什么)
有没有办法重构这个添加的逻辑?
这些是实例方法,对吧?做一个对象到处需要数据时的做法,在构造时传入:
mailer = WhateverMailer.new(locale: I18n.locale)
mailer.welcome(user_id, store_id)
所以您只需将语言环境作为实例变量存储在您的邮件程序中。查看其余方法,似乎该模式可以帮助清理其他内容,例如 user_id
.