Reputation: 16734
The end goal is to create a helper found at the end called show_status(contact,event).
Event can be any object, Email, Letter, etcetera. The combination of an Email template sent to a Contact is a specific record ContactEmail. Because each event has a different corresponding Model I need to do the .find on, I have duplication. There must be a better way!
def show_email_status(contact, email)
@contact_email = ContactEmail.find(:first, :conditions => {:contact_id => contact.id, :email_id => email.id })
if ! @contact_email.nil?
return @contact_email.status.to_s + " (" + @contact_email.date_sent.to_s + ")"
else
return "no status"
end
end
def show_call_status(contact, call)
@contact_call = ContactCall.find(:first, :conditions => {:contact_id => contact.id,
:call_id => call.id })
if ! @contact_call.nil?
return "sent " + @contact_call.date_sent.to_s(:long)
else
return "no status"
end
end
def show_letter_status(contact, letter)
@contact_letter = ContactLetter.find(:first, :conditions => {:contact_id => contact.id,
:letter_id => letter.id })
if ! @contact_letter.nil?
return "sent " + @contact_letter.date_sent.to_s(:long)
else
return "no status"
end
end
def show_voicemail_status(contact, voicemail)
@contact_event = ContactEvent.find(:first, :conditions => {:contact_id => contact.id,
:event_id => voicemail.id,
:type => "voicemail"})
if ! @contact_event.nil?
return "sent " + @contact_event.date_sent.to_s(:long)
else
return "no status"
end
end
def show_postalcard_status(contact, postalcard)
@contact_postalcard = ContactPostalcard.find(:first, :conditions => {:contact_id => contact.id,
:postalcard_id => postalcard.id })
if ! @contact_postalcard.nil?
return "sent " + @contact_postalcard.date_sent.to_s(:long)
else
return "no status"
end
end
def show_status(contact, call_or_email_or_letter_or_voicemail)
model_name = call_or_email_or_letter_or_voicemail.class.name.tableize.singularize
send "show_#{model_name}_status", contact, call_or_email_or_letter_or_voicemail
end
Upvotes: 2
Views: 171
Reputation: 64363
Try this:
def show_status(contact, target)
target_class= target.class.name
target_id = target_class.foreign_key.to_sym
klass = "Contact#{target_class}".constantize
r = klass.first(:conditions => {:contact_id => contact.id,
target_id => target.id})
return "no status" unless r
# If you want to treat ContactEmail differently then use the next line
#return "#{r.status} (#{r.date_sent})" if target.is_a?(ContactEmail)
"sent (#{r.date_sent.to_s(:long)})"
end
Usage:
contact = Contact.find(..)
email = Email.find(..)
letter = Letter.find(..)
call = Call.find(..)
show_status(contact, email)
show_status(contact, letter)
show_status(contact, call)
Edit 1
A better approach is to add a method to the Contact model.
class Contact < ActiveRecord::Base
# assuming you have following associations
has_many :contact_emails
has_many :contact_calls
has_many :contact_letters
# etc..
def communication_status target
target_class= target.class.name
target_id = target_class.foreign_key.to_sym
assoc_name = "contact_#{target_class.tableize}"
r = send(assoc_name).send("find_by_#{target_id}", target.id)
return "no status" unless r
"sent (#{r.date_sent.to_s(:long)})"
end
end
Usage:
contact = Contact.find(..)
email = Email.find(..)
letter = Letter.find(..)
call = Call.find(..)
contact.communication_status(email)
contact.communication_status(email)
contact.communication_status(letter)
contact.communication_status(call)
Upvotes: 4
Reputation: 42863
Combine all those models into one and then have an attribute that defines the type of media such as email, phone, paper, etc instead of having a different model for each type.
Then you can pass the object which will have a media type as the only parameter and with that object you can access the contact with media_object.contact
and the media_type with media_object.media_type
which you can use to search for the user and the type of media.
def show_media_object(mo)
options = {conditions = ['media_type = ? AND contact_id = ?',
mo.media_type, mo.contact_id]}
if @media_type = MediaObject.find(:first, options)
"sent " + @mo.updated_at
else
"Sorry, your SOL"
end
end
Upvotes: 0