2

Michael Hartl の Rails Tutorial 2nd Ed Chapter 10 Exercise 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 パーシャルごとにコレクション全体が再度レンダリングされますが、私が望んでいたのは、親パーシャルで使用された元のコレクションからローカル変数を渡すことでした。

renderの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 %>

次に、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 } %>

別の質問: ローカル変数ではなく、オブジェクトを渡すタイミングについて混乱しています。この場合、ローカル変数micropostとを渡す必要がありまし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 %>

以下の変更 -

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. render の最初の引数として文字列を渡すと、部分的であると見なされます
  2. ローカル変数を渡すこの方法は Rails 3 にのみ適用されます。Rails 4 ではローカル変数を locals ハッシュ経由で渡す必要があると思います
于 2013-11-26T01:27:39.393 に答える