問題描述
DRYing rails 視圖:partial vs helper (DRYing rails view: partial vs helper)
I need an advice on best practices for DRYing view code. I have three classes (NewsItem, RssItem and BlogItem) in my app, that use separate views, but have similar parts in them. One of the parts is such:
<% if current_user %>
<footer>
<%= marks_bar(@item) %>
<%= favorite_button(@item, "blog_item") || delete_from_favorite_button(@item, "blog_item") %>
<%= share_button(@item) %>
<% if current_user.is_mine?(@item) %>
<div><%= link_to "Edit", edit_user_blog_item_path(current_user, @item) %></div>
<% end %>
</footer>
<% end %>
It's almost equal for all three classes, so I decided to take it out to some separate place. And here I am confused: should I use a partial or helper method for it? I know that helpers are used mostly for separating ruby code from HTML, but in this case the helper will look like:
def toolbar_for(item, type_str, edit_path)
if current_user
content_tag(:footer) do |b|
marks_bar(item).to_s <<
(delete_from_favorite_button(item, type_str) || favorite_button(@item, type_str)).to_s <<
share_button(@item).to_s <<
(content_tag(:div) { link_to("Edit", edit_path)} if current_user.is_mine?(@item)).to_s
end
end
end
So, there is almost no HTML code here.
Could you please give me advice, what method is better in your opinion and why? Also, are there some performance issues in these methods (for example multiple String concatenation or frequent partial loading might be costly)? (This app is rather high‑loaded)
‑‑‑‑‑
參考解法
方法 1:
I would say this is a great example of a partial.
I reserve helpers for generating arbitrary dynamic content. This is kind of a loose description so how about an example: I would make a helper that splits an array of ActiveRecord objects and displays them into N columns. In this case the passed object's structure is being leveraged in some way in order to generate the content, but the content itself is unimportant. If you think about it, form_for also fits this description.
Conversely partials are great for 'static' content, that needs to be reused on multiple pages. For instance you would create a partial to render a single item. The partial determines a particular items 'static' representation.
Your example fits much better into the second bin, in my opinion. Since the @item
isn't being manipulated to generate the content, in fact it is hardly being used. It seems this helper is mostly glue code for other appropriately created helpers (share_button
and marks_bar
). The perfect use case for a partial!
方法 2:
I'd use a view partial for this. Good rule of thumb: if HTML is the output, use a partial. Helpers are not the junk drawer of your Rails app—they should really be used to output data, not presentation. Though I usually recommend people eschew helpers in general, in favor of presenters, which are vastly underutilized in the Rails world.
(by sandrew、diedthreetimes、Keith Gaddis)