在我的Rails应用程序中,我有以下关联:
在视频模型中,我有以下方法。
# models/video.rb
def genre_name
genre.present? ? genre.name : ''
end
这是为了在视图中避免这样的事情(这看起来很混乱):
# views/videos/show.html.erb
<% if @video.genre.present? %>
<%= @video.genre.name %>
<% else %>
No Genre Present
<% end %>
相反,我可以这样做(看起来更整洁)
# views/videos/show.html.erb
<%= @video.genre_name %>
然而,在视频模型中询问有关类型的信息并不合适。组织此代码的最佳方法是什么?我应该使用帮手吗?
答案 0 :(得分:2)
您可以在视图中写下
<%= @video.genre.try(:name) || 'No Genre Present' %>
如果您不需要后备文字,只需
<%= @video.genre.try(:name) %>
Read more about Object#try
here
如果您希望在name
为空字符串(而不仅仅是nil
)时进行后备,则可以使用Object#presence
<%= @video.genre.try(:name).presence || 'No Genre Present' %>
答案 1 :(得分:2)
如果你发现自己做了很多这样的事情,可能值得研究装饰模式,它可以容纳这样的视图逻辑。 (我非常喜欢使用Draper来实现此目的,但是推出自己的天真实现并不是很困难。)
然后,您的装饰器逻辑可能如下所示:
class VideoDecorator
def genre_name
object.genre.try(:name).presence || "Fallback"
end
end
您可以在控制器中渲染时在装饰器中包装模型:
@video = Video.find(params[:id])
respond_with @video.decorate
你的观点'逻辑'(或缺乏)可能看起来像这个应用程序范围:
<%= @video.genre_name %>
Thoughtbot对装饰器模式here
有很好的解释