2

最終的な目標は、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
4

2 に答える 2

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)
于 2010-08-20T05:03:06.927 に答える
0

これらすべてのモデルを 1 つに結合し、タイプごとに異なるモデルを持つ代わりに、電子メール、電話、紙などのメディアのタイプを定義する属性を持ちます。

次に、唯一のパラメーターとしてメディア タイプを持つオブジェクトを渡すことができます。そのオブジェクトを使用して連絡先にアクセスし、ユーザーとメディアのタイプを検索するために使用できるmedia_object.contactmedia_type を使用できます。media_object.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
于 2010-08-20T04:20:46.983 に答える