Рендирайте частично в Ruby on rails колекция умножава елементи

Искам да покажа списък с елементи в страница в Ruby-on-Rails. Използвам частични

в моя index.html.erb файл имам:

<%= @lista = News.find(:all, :order => Document::COL_DATE + ' DESC, id DESC')
    render :partial => "newsitem",
           :layout => "list_news",
           :spacer_template => "spacer",
           :collection => @lista
%>

в _list_news.html.erb имам:

<div class="news">
  <%= yield %>
</div>

в _spacer.html.erb имам <hr/>

в _newsitem.html.erb имам

<%= newsitem_counter + 1 %>
<!-- Code to print details for one item -->

Проблемът е, че отпечатва списъка няколко пъти:

Ако списъкът има 3 елемента, той ги показва 3 пъти: 1,2,3,1,2,3,1,2,3.
Ако има 7 елемента, тези елементи се отпечатват 7 пъти.

Какво не е наред в моя код?


person True Soft    schedule 05.02.2010    source източник
comment
вмъкнете малко регистриране във вашия код за изглед, за да видите какво се извиква многократно.   -  person klochner    schedule 05.02.2010


Отговори (2)


Опцията :layout обикновено се използва с :action или единичен :partial, а не с :collection's. Проблемът: yield се извиква за всеки елемент в списъка.

Трябва да погледнете източниците, за да разберете защо :layout и :collection действат по този начин; но е достатъчно да се каже, че вашият код вероятно просто трябва да бъде пренаписан, така че да не разчита на съвместната работа на :layout и :collection.

Ето един начин, по който бихте могли да го направите, при предположението, че повторното използване на този код в други изгледи е с висок приоритет. Освен ако не използвате много кеширане, изобразяването на всяка част обикновено е доста бавно, особено ако вашият news_feed има много елементи, така че го консолидирах в един.

controller/news_controller.rb

class NewsController < ApplicationController
   def index
     @news_feed = News.find(:all, 
                            :order => Document::COL_DATE + ' DESC, id DESC')
   end
end

views/news/index.html.erb

<%= render :partial => "news_feed",
       :locals => { :news_feed => @news_feed} %>

views/news/_news_feed.html.erb

<ul class="news">
  <% news_feed.each_with_index do |news_item, news_item_counter| %>
     <li>
       <%= newsitem_counter + 1 %>
      <%# Code to print details for one item %>
     </li>
  <% end %>
</ul>

Ако изобразяването на цял куп части е добре за вас от гледна точка на времето за изпълнение, може да намерите тази реализация на views/news/_news_feed.html.erb по-хубава:

<div class="news">
  <%= render :partial => 'news_item', :collection => news_feed, :spacer_template => "horizontal_break" %> 
</div>

views/news/_news_item.html.erb

<%= newsitem_counter + 1 %>
<%# Code to print details for one item %>

views/news/_horizontal_break.html.erb

<hr />

Така че вместо да изобразявате :layout, вие изобразявате един голям частичен, който обвива колекцията.

person Tim Snowhite    schedule 05.02.2010
comment
Това писах, когато те видях да публикуваш отговор - и твоят е по-подробен от моя. +1. - person Austin Fitzpatrick; 05.02.2010
comment
Благодаря за толкова подробен отговор. Използвах първия метод. - person True Soft; 06.02.2010

Вижте stackoverflow.com/questions/666468/
person Aditya Sanghi    schedule 27.06.2010