views:

22

answers:

1

I have several similar models ContactEmail, ContactLetter, etcetera.

Each one belongs_to a Contact

Each contact belongs_to a Company

So, what I did was create a virtual attribute for ContactEmail:

  def company_name
    contact = Contact.find_by_id(self.contact_id)

    return contact.company_name

  end

Question: How can I get an easy list of all company_name (without duplicates) if I have a set of ContactEmails objects (from a find(:all) method, for example)?

When I try to do a search on ContactEmail.company_name using the statistics gem, for example, I get an error saying that company_name is not a column for ContactEmail.

A: 

Assuming your ContactEmail set is in @contact_emails (untested):

@contact_emails.collect { |contact_email| contact_email.company_name }.uniq

You don't need the virtual attribute for this purpose though. ActiveRecord sets up the relationship automatically based on the foreign key, so you could take the company_name method out of the ContactEmail model and do:

@contact_emails.collect { |contact_email| contact_email.contact.company_name }.uniq

Performance could be a consideration for large sets, so you might need to use a more sophisticated SQL query if that's an issue.

EDIT to answer your 2nd question

If company_name is a column, you can do:

ContactEmail.count(:all, :joins => :contact, :group => 'contact.company_name')

On a virtual attribute I think you'd have to retrieve the whole set and use Ruby (untested):

ContactEmail.find(:all, :joins => :contact, :select => 'contacts.company_name').group_by(&:company_name).inject({}) {|hash,result_set| hash.merge(result_set.first=>result_set.last.count)}

but that's not very kind to the next person assigned to maintain your system -- so you're better off working out the query syntax for the .count version and referring to the column itself.

zetetic
I see...company_name is also a virtual attribute of contact, but I assume that is okay.
Angela
Would there be a way, since I have to go through the company_names anyway, to COUNT the total number of instances that fall within a given company_name, kind of like using GROUP?
Angela
company_name is not a column of contact. It is also a virtual attribute. So it means I'd have to do that huge long thing?
Angela
My advice would be to *not* use the "huge long thing", because it is kinda obscure and potentially bad for performance. Your best bet is to figure out the actual column and table for the virtual attribute, then write a Rails find method to do the query, or just straight SQL and use `.find_by_sql`. If you post a new question on SO with the approprate models/tables I'll bet you get a good answer.
zetetic
Okay this answers the question: I can access a company name by Contactemail.contact.company.name. Thanks...now the question is how do I display the count for each company?
Angela