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

时间:2012-04-19 04:28:24

标签: ruby-on-rails-3 collections partials railstutorial.org

通过Michael Hartl's Rails Tutorial 2nd Ed Chapter 10 Exercise 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>

清单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>

我的方法是创建此文件 共享/ _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:选项进行渲染,但没有运气。

有人知道答案吗?谢谢!

2 个答案:

答案 0 :(得分:5)

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

所以,答案应该是:

偏... 应用程序/视图/共享/ _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>

添加到部分: 可以稍微重构一下,并将用户条件包含在partial中。所以,你可以将部分分为:

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

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

然后对render的调用也必须传入用户。所以, 代码清单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 } %>

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

有人知道为什么在这种情况下这是真的吗?

答案 1 :(得分:0)

以下稍微简洁的实现对我有用(在Rails 3.2.14中):

部分没有变化(这里为后代列出):

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

对以下内容的更改 -

apps / views / microposts / _micropost.html.erb:

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

apps / views / shared / _feed_item.html.erb:

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

注意:

  1. 当传递字符串作为渲染的第一个参数时,它被假定为部分
  2. 这种传递局部变量的方法仅适用于Rails 3,我相信Rails 4 may require local variables to be passed via the locals hash