Rails 3嵌套Partials,Collections,Locals(Rails教程第2版:第10章,练习5)

Bre*_*ers 2 collections partials ruby-on-rails-3 railstutorial.org

通过Michael Hartl的Rails教程第2章第10章练习5,我遇到了部分和集合的问题,并在部分内部使用了部分.

第10章,练习5指出: "使用partials,消除清单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>
Run Code Online (Sandbox Code Playgroud)

代码清单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>
Run Code Online (Sandbox Code Playgroud)

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

<%= link_to "delete", item, method:  :delete,
                                 confirm: "You sure?",
                                 title:   item.content %>
Run Code Online (Sandbox Code Playgroud)

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

代码清单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>
Run Code Online (Sandbox Code Playgroud)

代码清单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>
Run Code Online (Sandbox Code Playgroud)

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

整个集合将再次为每个_item_delete_link部分渲染,而我想要的是从父部分中使用的原始集合中传递局部变量.

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

有谁知道答案?谢谢!

Bre*_*ers 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 %>
Run Code Online (Sandbox Code Playgroud)

代码清单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>
Run Code Online (Sandbox Code Playgroud)

代码清单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>
Run Code Online (Sandbox Code Playgroud)

添加到PARTIAL: 可以对此进行重构,并将用户条件包含在partial中.所以,你可以将部分分为:

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

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

然后对render的调用也必须传入用户.那么,代码清单10.46:app/views/microposts/_micropost.html.erb

<%= render partial: "shared/item_delete_link", 
           locals: { item: micropost, user: @user } %>
Run Code Online (Sandbox Code Playgroud)

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

<%= render partial: "shared/item_delete_link", 
          locals: { item: feed_item, user: @user } %>
Run Code Online (Sandbox Code Playgroud)

另一个问题: 我很困惑何时传入对象,而不是局部变量.在这种情况下,我在当地的变量传递micropostfeed_item,但实例变量@user.

谁知道为什么在这种情况下这是真的?