最终目标是创建一个名为 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
最佳答案
试试这个:
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)
关于ruby-on-rails - 如何在 Rails 中调用类似模型时使此代码(帮助程序)干燥?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3527988/