Rails 部分 - 与当地人的条件
Rails Partials - conditionality with locals
我在 Rails 部分使用了以下代码,用于某些邮件程序,但我对我的解决方案不满意,感觉这远非最佳。
我有一封电子邮件
来自我的邮件:
def the_email_i_am_sending(user, inquiry, params = {})
get_variables(inquiry) #This also provides access to my `@user` object
@contact_name = [params[:guest_last_name].to_s, " ", params[:guest_first_name].to_s].join
我总是有 @user
,但有时某个特定的合作伙伴会调用我们的 API,并附加上文定义的 [:guest_last_name]
和 [:guest_first_name]
参数。这允许我将 @contact_name
定义为单独的实例变量。
当这是 .present?
即不是零时,我想在电子邮件的字段中呈现 @contact_name
而不是从我们的数据库中提取的 @user.login
。
然后我的邮件程序视图使用以下代码来决定将呈现哪个部分。
<% if @contact_name.present? %>
<%= render 'meet_your_guest_v3', tujia_guest: @contact_name %>
<% else %>
<%= render 'meet_your_guest_v3' %>
<% end %>
然后我的解决方案是在邮件程序中呈现的部分中使用此代码。看起来有点冗长,但我不确定 local_assigns.has_key?
的正确用法
<% if local_assigns.has_key?(:partner_guest) %>
<%= partner_guest %> <p>(via our partner</p>
<% else %>
<%= @user.login %>
<% end %>
有没有更好的方法?
关于处理 controller/mailer 中的参数,您绝对应该遵循@Jon 的建议。此外,您应该每次都将 @contact_name 传递给底层部分,无论它是否存在,然后仅检查您要渲染它的位置(如果存在)。这样你就可以跳过一个条件:
#email_view.html.erb
render 'meet_your_guest_v3', parnter_guest: @contact_name
_contact_name.html.erb
<% partner_guest.present? %>
...
进一步的步骤可能是使用一个特殊的装饰器对象,它会处理表示逻辑。它会检查 contact_name 是从外部还是从模型提供的,并为 contact_name 呈现所需的 html 标签(或者它可以 return 它作为字符串)。请参阅以下使用 draper gem 的伪代码:
class MyController < ApplicationController
def send_mail
@user = User.find(...).decorate(
contact_name: [params[:guest_last_name].to_s, " ", params[:guest_first_name].to_s].join
)
MyMailer.the_email_i_am_sending(@user)
end
end
class MyMailer < ApplicationMailer
def the_email_i_am_sending(user)
@user = user
mail(to: ..., subject: ...)
end
end
class UserDecorator < Draper::Decorator
def contact_name_tag
if (contact_name.present?)
h.content_tag(:div, contact_name)
else
h.content_tag(:div, user_name)
end
end
end
#email_view.html.erb
<%= @user.contact_name_tag %>
但是,如果表示逻辑不是很复杂,那么使用几个条件语句并可能将它们提取到基本的 rails 帮助器中就可以了,而使用演示器可能有点矫枉过正
我在 Rails 部分使用了以下代码,用于某些邮件程序,但我对我的解决方案不满意,感觉这远非最佳。
我有一封电子邮件
来自我的邮件:
def the_email_i_am_sending(user, inquiry, params = {})
get_variables(inquiry) #This also provides access to my `@user` object
@contact_name = [params[:guest_last_name].to_s, " ", params[:guest_first_name].to_s].join
我总是有 @user
,但有时某个特定的合作伙伴会调用我们的 API,并附加上文定义的 [:guest_last_name]
和 [:guest_first_name]
参数。这允许我将 @contact_name
定义为单独的实例变量。
当这是 .present?
即不是零时,我想在电子邮件的字段中呈现 @contact_name
而不是从我们的数据库中提取的 @user.login
。
然后我的邮件程序视图使用以下代码来决定将呈现哪个部分。
<% if @contact_name.present? %>
<%= render 'meet_your_guest_v3', tujia_guest: @contact_name %>
<% else %>
<%= render 'meet_your_guest_v3' %>
<% end %>
然后我的解决方案是在邮件程序中呈现的部分中使用此代码。看起来有点冗长,但我不确定 local_assigns.has_key?
<% if local_assigns.has_key?(:partner_guest) %>
<%= partner_guest %> <p>(via our partner</p>
<% else %>
<%= @user.login %>
<% end %>
有没有更好的方法?
关于处理 controller/mailer 中的参数,您绝对应该遵循@Jon 的建议。此外,您应该每次都将 @contact_name 传递给底层部分,无论它是否存在,然后仅检查您要渲染它的位置(如果存在)。这样你就可以跳过一个条件:
#email_view.html.erb
render 'meet_your_guest_v3', parnter_guest: @contact_name
_contact_name.html.erb
<% partner_guest.present? %>
...
进一步的步骤可能是使用一个特殊的装饰器对象,它会处理表示逻辑。它会检查 contact_name 是从外部还是从模型提供的,并为 contact_name 呈现所需的 html 标签(或者它可以 return 它作为字符串)。请参阅以下使用 draper gem 的伪代码:
class MyController < ApplicationController
def send_mail
@user = User.find(...).decorate(
contact_name: [params[:guest_last_name].to_s, " ", params[:guest_first_name].to_s].join
)
MyMailer.the_email_i_am_sending(@user)
end
end
class MyMailer < ApplicationMailer
def the_email_i_am_sending(user)
@user = user
mail(to: ..., subject: ...)
end
end
class UserDecorator < Draper::Decorator
def contact_name_tag
if (contact_name.present?)
h.content_tag(:div, contact_name)
else
h.content_tag(:div, user_name)
end
end
end
#email_view.html.erb
<%= @user.contact_name_tag %>
但是,如果表示逻辑不是很复杂,那么使用几个条件语句并可能将它们提取到基本的 rails 帮助器中就可以了,而使用演示器可能有点矫枉过正