Как я могу выполнить рефакторинг, требуя так много петель for в рельсах? - PullRequest
1 голос
/ 15 мая 2010

Мне нужна помощь в рефакторинге этой многопетлевой вещи. Вот что у меня есть:

Кампания has_many Контакты
Кампания также имеет много моделей, которые являются шаблонами: (электронная почта, звонок и письмо).

Поскольку я ищу просроченные записи для каждого, я создал массив с именем Event, который я хотел бы просмотреть в цикле, который содержит ['email', 'call', 'letter'].

Мне нужен список всех электронных писем, звонков и писем, которые «просрочены» для каждого контакта, принадлежащего кампании. Просроченный платеж определяется методом from_today, который просматривает дату, в которую Контакт был введен в систему, и количество дней, которое должно пройти для любого данного События. from_today () выводит количество дней с сегодняшнего дня, когда событие должно быть выполнено для данного контакта.

Вот что я сделал, это работает для всех электронных писем в кампании по всем контактам. Я собирался попытаться создать еще один цикл do для изменения имен классов.

Не был уверен, с чего начать: named_scope, вставить некоторые вещи в метод, и так далее, или - минимум, чтобы иметь возможность динамически изменять имена классов, чтобы, по крайней мере, он повторялся три раза по различным событиям, а не повторял код три раза:

<% @campaigns.each do |campaign| %>
   <h2><%= link_to campaign.name, campaign %></h2>

   <% @events.each do |event| %>
       <%= event %>
       <% for email in campaign.emails %>
          <h4><%= link_to email.title, email  %> <%= email.days %> days</h4>

          <% for contact in campaign.contacts.find(:all, :order => "date_entered ASC" ) %>
             <% if (from_today(contact, email.days) < 0) %>
                <% if show_status(contact, email) == 'no status'%>
                    <p> <%= full_name(contact) %> 
                        is <%= from_today(contact,email.days).abs%> days overdue:
                        <%= do_event(contact, email) %>
                    </p>
                <% end %>
             <% end %>
          <% end %>
       <% end %>
     <% end %>
<% end %>

Ответы [ 2 ]

1 голос
/ 15 мая 2010

Просто чтобы добавить ответ Патрика, я бы также использовал опцию: collection в render, чтобы еще больше упростить это, например, иметь частичный _contact.html.erb для отображения каждого контакта:

<% if (from_today(contact, email.days) < 0) %>
    <% if show_status(contact, email) == 'no status'%>
      <p> <%= full_name(contact) %> 
          is <%= from_today(contact,email.days).abs%> days overdue:
          <%= do_event(contact, email) %>
      </p>
    <% end %>
  <% end %>
<% end %>

и затем визуализируйте коллекцию contacts с

= render :partial => "contact", :collection => @contacts

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

1 голос
/ 15 мая 2010

Я бы поместил вывод для каждого ресурса в частичное, вот так:

<% @campaigns.each do |campaign| %>
  <h2><%= link_to campaign.name, campaign %></h2>
  <%= render 'events', :events => campaign.events %>
<% end %>

затем в app / views / campaigns / _events.html.erb

<% events.each do |event| %>
  <%= event %>
  <%= render 'emails', :emails => event.emails %>
<% end %>

затем в app / views / campaigns / _emails.html.erb

<% emails.each do |email| %>
  <h4><%= link_to email.title, email  %> <%= email.days %> days</h4>
  <%= render 'contacts', :contacts => email.contacts.all(:order => "date_entered ASC", :email => email) %>
<% end %>

затем в app / views / campaigns / _contacts.html.erb

<% contacts.each do |contact| %>
  <% if (from_today(contact, email.days) < 0) %>
    <% if show_status(contact, email) == 'no status'%>
      <p> <%= full_name(contact) %> 
          is <%= from_today(contact,email.days).abs%> days overdue:
          <%= do_event(contact, email) %>
      </p>
    <% end %>
  <% end %>
<% end %>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...