最终目标是创建一个名为show_status(contact,event)的帮助器。
事件可以是任何对象,电子邮件,信件等。发送给联系人的电子邮件模板的组合是特定记录ContactEmail。因为每个事件都有不同的相应模型,我需要执行.find,我有重复。肯定有更好的办法!
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
答案 0 :(得分:4)
试试这个:
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
用法:
contact = Contact.find(..)
email = Email.find(..)
letter = Letter.find(..)
call = Call.find(..)
show_status(contact, email)
show_status(contact, letter)
show_status(contact, call)
修改1
更好的方法是向Contact模型添加方法。
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
用法:
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)
答案 1 :(得分:0)
将所有这些模型合并为一个,然后有一个属性来定义媒体类型,如电子邮件,电话,纸张等,而不是为每种类型设置不同的模型。
然后您可以将具有媒体类型的对象作为唯一参数传递,使用该对象,您可以访问media_object.contact
的联系人以及可以用于搜索的media_object.media_type
的media_type用户和媒体类型。
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