2010-05-01 3 views
1

Мне, вероятно, понадобится рефакторинг в два этапа, так как я все еще разрабатываю проект и изучаю прецеденты, поскольку я иду, чтобы почесать свой собственный зуд. У меня есть три модели: письма, звонки, электронные письма. У них есть некоторые сходства, но я ожидаю, что они также будут иметь несколько разных атрибутов, как вы можете сказать из их описания.Как я могу использовать одну вспомогательную работу на разных моделях?

В идеале я мог бы реорганизовать их как Events, с типом как буквы, звонки, электронные письма, но не знал, как расширить подклассы.

Моя насущная потребность заключается в следующем: у меня есть помощник, который проверяет на статус, был ли отправлен определенному контакту электронной почты (например):

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 
    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 @contact_call.status 
    end 
end 

Я хотел бы иметь возможность просто иметь один вспомогательный show_status, где я могу сказать show_status (контакт, вызов) или show_status (контакт, электронная почта), и он будет знать, искать ли объект @contact_c all или @contact_email.

Да, было бы проще, если бы это было просто @contact_event, но я хочу сделать небольшой рефакторинг, пока я запускаю программу, и это сделает возможность сделать историю для данного контакта намного проще ,

Спасибо!

ПРИМЕЧАНИЕ: В настоящее время у меня есть статус атрибута contact_email, contact_call и т. Д. Contact_email создается только при отправке сообщения электронной почты, поэтому нет контакта, если письмо не отправлено, и мне нужно знать, что статус «unsent» ...

ответ

0

Вы можете переместить помощника в Contact модели.

class Contact < ActiveRecord::Base 

    has_many :contact_emails 
    has_many :contact_calls 
    has_many :contact_letters 

    def event_status event 
    assoc_name = "Contact#{event.class.name}".pluralize.underscore 
    foreign_key = "%s_id" % event.class.name.underscore 
    ce = send(assoc_name).first(:conditions => {foreign_key => event.id}) 
    ce ? ce.status : nil 
    end 

end 

Теперь вы можете получить статус следующим образом:

contact.event_status(email1) 
contact.event_status(letter2) 
contact.event_status(call12) 

Это устраняет необходимость в различных помощниках. Один метод решения различных событий.

+0

Привет, это получает ошибку, как не следует: нет такой колонки: emails.email_id: SELECT * FROM "письма" WHERE ("электронная почта" .contact_id = 1 AND («emails». «email_id» = 2)) Идентификатор для писем будет emails.id Я считаю ... но не ясно, как настроить это? – Angela

+0

Я удалил pluralize, и теперь я получаю это: undefined method '> = 'for {: conditions => {" email_id "=> 2}}: Hash Это выглядит как правильные параметры для: условий, но дон 't знать, что неопределенный метод> = is ... – Angela

+0

Обновлен ответ, посмотрите. –

0

Поскольку у вас уже есть show_call_status и show_email_status, вы можете написать третий show_letter_status.

Затем используйте:

def show_status(contact, call_or_email_or_letter) 
    model_name = call_or_email_or_letter.class.name.tableize.singularize 
    send "show_#{model_name}_status", contact, call_or_email_or_letter 
end 
+0

поэтому я создаю 3 помощника, а затем один мега-помощник? – Angela

+0

Так в представлении, я использую: <% = show_status (@ контакт, электронная почта)%> я получаю следующее сообщение об ошибке: неопределенный метод 'show_email_status, контакт, call_or_email» для # Они находятся в файле contacts_helper.rb кстати – Angela

1

Предполагая из примера, что ваши ассоциации выглядеть следующим образом:

class Contact 
    has_many :emails, :through => :contact_emails 
    has_many :calls, :through => :contact_calls 
end 

и статус является атрибутом ContactEmail/ContactCall, но вам нужен статус объекта Email/вызова, а затем (на основе Kandada ответа здесь):

class Contact 
    def event_status(event) 
    event_type = event.class.name 
    foreign_key = ("%s_id" % event_type.downcase).to_sym 

    assoc = "Contact#{event_type}".tableize 
    contact_event = send(:assoc).first(:conditions => {foreign_key => event.id}) 
    contact_event.try(:status) 
    end 
end 
Смежные вопросы