在一个ERB块中渲染多个表达式的输出

mar*_*ion 5 ruby ruby-on-rails erb helper ruby-on-rails-4

我有一个看起来像这样的帮手:

if current_user.find_voted_items(vote_scope: :inspired).include?(post)
   link_to vote_inspired_post_path(post, vote_scope: :inspired), method: :post, data: { confirm: 'Are you sure this post Inspires you?' }, class: "btn btn-default" do
    "<i class='fa fa-lightbulb-o'></i> <br />Inspired".html_safe
   end
   link_to vote_happy_post_path(post, vote_scope: :happy), method: :post, data: { confirm: 'Are you sure this post makes you happy?' }, class: "btn btn-success" do
    "<i class='fa fa-smile-o'></i> <br />Happy".html_safe
   end
   link_to vote_disappointed_post_path(post, vote_scope: :disappointed), method: :post, data: { confirm: 'Are you sure this post disappointed you?' }, class: "btn btn-info" do
    "<i class='fa fa-meh-o'></i> <br />Disappointed".html_safe
   end
   link_to vote_upset_post_path(post, vote_scope: :upset), method: :post, data: { confirm: 'Are you sure this post upsets you?' }, class: "btn btn-inverse" do
    "<i class='fa fa-frown-o'></i> <br />Upset".html_safe
   end
end
Run Code Online (Sandbox Code Playgroud)

我需要<i>渲染所有链接及其嵌套标记 - 但由于某种原因,这个版本只是渲染最后一行.

所有这些都在一个show_vote_buttons(post)被调用的方法中,在视图中被调用如下:<%= show_vote_buttons(@post) %>

解决这个问题的最佳方法是什么?

pot*_*hin 5

基本上,这背后的原因是<%= %>渲染show_vote_buttons方法的输出.此方法不显式返回任何内容,因此返回最后一个计算表达式,在您的情况下,返回最后一个link_to输出.

在一般情况下,如果您没有使用辅助方法并且仅使用多次link_to调用粘贴它的正文,您将获得相同的行为.原因是类似的:<%= %>不渲染每个link_to,它在内部执行代码<%= %>,然后输出最后一个计算表达式的结果.

我看到两种不同的方法来改变输出:

  1. Helper方法:连接所有计算表达式的输出并打印为一个字符串:
    1.1使用<< 和括号()围绕每个link_to;
    1.2创建一个带双引号的字符串,"并在其中插入每个link_to输出#{};
    1.3使用concat;
  2. 部分视图:从现有的辅助方法构建一个单独的视图,并用于<%= %>输出每个方法link_to.

PS在测试了所有四种方法之后,我得出了一个结论(这里有个人观点),第二种方法更为可取,至少因为它在视图中保持渲染并避免可能看起来混乱的连接.例如,在Devise gem中使用类似的方法,其中所有共享链接都位于app/views/devise/shared/_links.html.erb partial中.