Визуализация шаблонов других контроллеров (Ruby on Rails) - PullRequest
2 голосов
/ 24 декабря 2009

Я создаю пример сайта, чтобы ознакомиться с RoR. Я до некоторой степени следовал книге «Agile Web Development с Rails», и сейчас я экспериментирую и использую ее в качестве справочного материала, однако мне не удалось найти ответ на мою проблему.

У меня есть две модели интереса, одна - супермаркет, другая - супермаркет. Очевидно, что сеть супермаркетов имеет кучу супермаркетов. То, что я пытаюсь сделать, - это получить базовую страницу «шоу» для одной сети супермаркетов, чтобы отобразить список принадлежащих ей супермаркетов.

Я также не хотел повторяться (потому что, по-видимому, это очень плохо), и поэтому я подумал, что могу использовать «render», чтобы вставить index.html.erb супермаркета на страницу supermarketchain / show.html.erb. , вот так:

<%= render :template => 'supermarkets/index' %>

Однако это привело к нулевому выводу на страницу.

Мой следующий подход состоял в том, чтобы сделать это частичным:

<div id="supermarket-list">
  <h1><%= I18n.t "supermarket.title" %></h1>

  <table>
    <% for s in @supermarkets %>
    <tr class="<%= cycle('list-line-odd', 'list-line-even') %>">
        <td> 
            <%= s.supermarketchain.name %>
        </td>
        <td>
            <%= s.address %>
        </td>
        <td class="list-actions">
            <%= link_to I18n.t("general.show"), s%> <br/>
            <%= link_to I18n.t("general.edit"), edit_supermarket_path(s) %> <br />
            <%= link_to I18n.t("general.delete"), s, :confirm => I18n.t("general.confirmation"), :method => :delete %>
        </td>
    </tr>
    <%end%>
  </table>
</div>

А затем используйте:

<% @supermarkets = Supermarket.all %>

<%= render :partial => 'supermarkets/supermarket' %>

Чтобы вставить его на выставочную страницу супермаркета.

Меня интересует, является ли это хорошей практикой. Мне кажется странным инициализировать переменную для использования частичным, когда то, что я хочу отобразить, является точным результатом действия «index» контроллера супермаркета. Комментарии?

Пожалуйста, попросите любые необходимые разъяснения.

Ответы [ 4 ]

1 голос
/ 04 января 2010

В Rails совершенно нормально рендерить партиалы с других контроллеров. Обычно, если частичное на самом деле не принадлежит какому-либо конкретному контроллеру, оно помещается в app/views/shared. В этом случае имеет смысл сохранить частичное с контроллером супермаркета, хотя я думаю.

Вот как вы можете использовать один и тот же частичный supermarkets/_supermarket.html.erb для обоих разделов. Частичное будет иметь локальную переменную supermarket доступны.

# supermarketchain/show.html.erb
<%= render :partial => "supermarkets/supermarket", :collection => @supermarketchain.supermarkets %>

# supermarkets/show.html.erb
<%= render :partial => "supermarket", :object => @supermarket %>
0 голосов
/ 24 декабря 2009

Я сам боролся с этим, но обнаружил, что он не поддерживается как способ визуализации частичных версий, и, поскольку я обычно доверяю соглашениям разработчиков Rails, я решил, что это, вероятно, не очень хорошая идея.

Я не думаю, что использование там шаблона будет работать, возможно, вы могли бы использовать render_to_string, но это кажется хакерским и может привести к еще большей головной боли в будущем.

Кроме того, если вы хотите визуализировать коллекцию, лучше всего установить переменную экземпляра в действии контроллера, а не в представлении.

def index
  @supermarkets = Supermarket.all
end

А потом в представлении index.html.erb позвоните:

<%= render @supermarkets %>

, который затем будет перебирать каждый элемент массива и отображать views/supermarkets/_supermarket.html.erb для каждого, при этом «супермаркет» будет текущим членом, доступным в партиале.

<%= supermarket.name %><br />
<%= supermarket.address %>

Я беспокоюсь о производительности многих из этих рендеров, но просто следите за журналами и временем, я думаю, что времена рендеринга и выполнения вручную в исходном представлении примерно одинаковы.

0 голосов
/ 24 декабря 2009

Хорошо, так что, если я правильно понял, у вас есть список сетей, и у каждой сети есть список супермаркетов, верно? Есть ли у вас связь между двумя моделями? Потому что это просто упростит вещи, если у вас есть. В этом случае предположим, что вы переименовали модель из «цепочки супермаркетов» в просто «цепочку» (чтобы устранить путаницу). Вы можете связать модели так:>

has_many: супермаркеты

А в модели супермаркета.

принадлежит_ к цепочке

Оттуда это просто проблема зацикливания:

<% if chain.supermarkets.count > 0 %>

#Do stuff.

<% end %>

Тем не менее, если вы не настроили контроллеры для получения этой информации, это может потребовать дополнительной работы.

0 голосов
/ 24 декабря 2009

Вместо этого вы можете сделать

<%= render :partial => 'supermarket', :collection => Supermarket.all, :as => :s %>

и частичное будет вызываться один раз для каждого супермаркета с именем переменной s.

...