2

通过Michael Hartl 的 Rails 教程第 2 版第 10 章练习 5,我遇到了部分和集合以及在部分中使用部分的问题。

第 10 章,练习 5 指出: “使用部分,消除代码清单 10.46 和代码清单 10.47 中删除链接中的重复项。”

清单 10.46:app/views/microposts/_micropost.html.erb

<li>
  <span class="content"><%= micropost.content %></span>
  <span class="timestamp">
    Posted <%= time_ago_in_words(micropost.created_at) %> ago.
  </span>
  <% if current_user?(micropost.user) %>
    <%= link_to "delete", micropost, method:  :delete,
                                     confirm: "You sure?",
                                     title:   micropost.content %>
  <% end %>
</li>

清单 10.47:app/views/shared/_feed_item.html.erb

<li id="<%= feed_item.id %>">
  <%= link_to gravatar_for(feed_item.user), feed_item.user %>
    <span class="user">
      <%= link_to feed_item.user.name, feed_item.user %>
    </span>
    <span class="content"><%= feed_item.content %></span>
    <span class="timestamp">
      Posted <%= time_ago_in_words(feed_item.created_at) %> ago.
    </span>
  <% if current_user?(feed_item.user) %>
    <%= link_to "delete", feed_item, method:  :delete,
                                     confirm: "You sure?",
                                     title:   feed_item.content %>
  <% end %>
</li>

我的方法是创建这个文件 shared/_item_delete_link.html.erb

<%= link_to "delete", item, method:  :delete,
                                 confirm: "You sure?",
                                 title:   item.content %>

然后在原始部分中使用这个部分,如下所示:

清单 10.46:app/views/microposts/_micropost.html.erb

<li>
    <span class="content"><%= micropost.content %></span>
    <span class="timestamp">
        Posted <%= time_ago_in_words(micropost.created_at) %> ago.
    </span>
    <% if current_user?(micropost.user) %>
  <%= render partial: 'shared/item_delete_link', collection: @microposts, as: :item %>
    <% end %>
</li>

清单 10.47:app/views/shared/_feed_item.html.erb

<li id="<%= feed_item.id %>">
  <%= link_to gravatar_for(feed_item.user), feed_item.user %>
  <span class="user">
    <%= link_to feed_item.user.name, feed_item.user %>
  </span>
  <span class="content"><%= feed_item.content %></span>
  <span class="timestamp">
    Posted <%= time_ago_in_words(feed_item.created_at) %> ago.
  </span>
  <% if current_user?(feed_item.user) %>
  <%= render partial: 'shared/item_delete_link', collection: @feed_items, as: :item %>
  <% end %>
</li>

这让我所有的测试都通过了,所以我认为它可以正常工作,直到我在浏览器中检查它:http: //grab.by/daUk

为每个 _item_delete_link 部分再次呈现整个集合,而我想要的是通过父部分中使用的原始集合中的局部变量。

我尝试使用locals: { }object:选项进行渲染,但没有运气。

有人知道答案吗?谢谢!

4

2 回答 2

5

弄清楚了。您希望将本地人传递给嵌套的部分,而不是重新渲染集合。为此,必须使用该locals: { symbol: :original-local }选项(使用新的 Ruby 哈希语法编写)。

所以,答案应该是这样的:

部分... app/views/shared/_item_delete_link.html.erb

<%= link_to "delete", item, method: :delete, confirm: "You sure?",
        title: item.content %>

清单 10.46:app/views/microposts/_micropost.html.erb

<li>
  <span class="content"><%= micropost.content %></span>
  <span class="timestamp">
    Posted <%= time_ago_in_words(micropost.created_at) %> ago.
  </span>
  <% if current_user?(micropost.user) %>
  <%= render partial: 'shared/item_delete_link', locals: { item: micropost } %>
  <% end %>
</li>

清单 10.47:app/views/shared/_feed_item.html.erb

<li id="<%= feed_item.id %>">
  <%= link_to gravatar_for(feed_item.user), feed_item.user %>
  <span class="user">
    <%= link_to feed_item.user.name, feed_item.user %>
  </span>
  <span class="content"><%= feed_item.content %></span>
  <span class="timestamp">
    Posted <%= time_ago_in_words(feed_item.created_at) %> ago.
  </span>
  <% if current_user?(feed_item.user) %>
  <%= render partial: 'shared/item_delete_link', locals: { item: feed_item } %>
  <% end %>
</li>

添加到部分: 可以稍微重构一下,也可以将用户条件包含到部分中。因此,您可以将部分变为:

app/views/shared/_item_delete_link.html.erb

<% if current_user?(item.user) %>
<%= link_to "delete", item, method:  :delete, 
       confirm: "You sure?", title: item.content %>
<% end %>

然后对渲染的调用也必须传入用户。所以,代码清单 10.46:app/views/microposts/_micropost.html.erb

<%= render partial: "shared/item_delete_link", 
           locals: { item: micropost, user: @user } %>

清单 10.47:app/views/shared/_feed_item.html.erb

<%= render partial: "shared/item_delete_link", 
          locals: { item: feed_item, user: @user } %>

另一个问题: 我对何时传入对象而不是局部变量感到困惑。在这种情况下,我必须传入局部变量micropostand feed_item,但实例变量@user.

任何人都知道为什么在这种情况下这是真的?

于 2012-04-19T15:51:14.547 回答
0

以下稍微不那么冗长的实现对我有用(在 Rails 3.2.14 中):

部分没有更改(此处列出以供后代使用):

<% if current_user?(item.user) %>
<%= link_to "delete", item, method:  :delete, 
       confirm: "You sure?", title: item.content %>
<% end %>

对以下内容的更改 -

应用程序/视图/microposts/_micropost.html.erb :

<%= render 'shared/micropost_delete_link', :item => micropost %>

应用程序/视图/共享/_feed_item.html.erb:

<%= render 'shared/micropost_delete_link', :item => feed_item %>

笔记:

  1. 当将字符串作为第一个参数传递给 render 时,它被假定为部分
  2. 这种传递局部变量的方法只适用于Rails 3,我相信Rails 4可能需要通过locals hash传递局部变量
于 2013-11-26T01:27:39.393 回答