views:

38

answers:

1

I am using the :collection to go through all the Contacts that are part of a given Campaign.

But within that Campaign I check for three different Models (each with their own partial). Feels like I am going through the list of Contacts 3x. How can I make this alot leaner?

<h2>These are past due:</h2>

<% @campaigns.each do |campaign| %>
   <h3>Campaign: <%= link_to campaign.name, campaign %></h3>
   <strong>Emails in this Campaign:</strong>
   <% for email in campaign.emails %>
      <h4><%= link_to email.title, email  %> <%= email.days %> days</h4>

         <% @contacts= campaign.contacts.find(:all, :order => "date_entered ASC" )%> <!--contacts collection-->   

         <!-- render the information for each contact -->
         <%= render :partial => "contact_email",
                    :collection => @contacts,
                    :locals => {:email => email} %>
    <% end %>

       Calls in this Campaign:
       <% for call in campaign.calls %>
          <h4><%= link_to call.title, call  %> <%= call.days %> days</h4>
          <% @contacts= campaign.contacts.find(:all, :order => "date_entered ASC" )%> <!--contacts collection-->      
         <!-- render the information for each contact -->
         <%= render :partial => "contact_call",
                    :collection => @contacts,
                    :locals => {:call => call} %>
       <% end %>

       Letters in this Campaign:
       <% for letter in campaign.letters %>
          <h4><%= link_to letter.title, letter  %> <%= letter.days %> days</h4>
          <% @contacts= campaign.contacts.find(:all, :order => "date_entered ASC" )%> <!--contacts collection-->      
         <!-- render the information for each contact -->
         <%= render :partial => "contact_letter",
                    :collection => @contacts,
                    :locals => {:letter => letter} %>
       <% end %>
<% end %>
+1  A: 

If you want them ordered by type (contacts, emails, letters, etc.) I don't think you'll be able to pull something more efficient (only to extract the repetitive code into separate partial and render collection there:

<% @contacts = campaign.contacts.find(...) %>
<% [:emails, :calls, :letters].each do |asset| %>
  <h4><%= asset.humanize %> in this campaign</h4>
  <%= render :partial => 'asset', :collection => campaign.send(asset), :as => :asset %>
<% end %> 

Then inside _asset partial you can use asset variable to refer to current objectr and reach contacts via @contacts instance var.

Eimantas
Hi, this is interesting...can you explain the :collection code a little, I think this look like something I could run with.
Angela
you dynamically call the method on `company` object (on each itteration it's one of `company.emails`, `company.calls` or `company.letters`).
Eimantas
Hih, I'm still lost on where the company object comes from? I don't have it in this set of code.The :partial I found I can just make a single partial if I pass th eright local variable.
Angela
sorry, that was a typo ,) updated the answer.
Eimantas
ah okay, that's what I thought....thanks! So...does "asset" exist in the partial as a class?
Angela
The `asset` variable will represent single object from rendered collection.
Eimantas
Hi, again. You wrote if I want them orderd by type....but what if I want them all ordered by, say, the :days attribute?
Angela
Hmmm I get the following error: undefined method `humanize' for :emails:Symbol
Angela
hmm, it doesn't seem to like sending the symbol :emails, "ecalls...is each of those just the name of the Class?
Angela
got it working, used "emails" instead of symbol...thanks!
Angela