Rails 3 Observers에 대한 나의 대안은 모델 내에 정의 된 콜백을 활용하면서 (위의 답변에서 agmin 상태로) "종속성 넘기기 ... 커플 링"을 관리하는 수동 구현입니다.
내 객체는 관찰자를 등록하는 기본 클래스에서 상속됩니다.
class Party411BaseModel
self.abstract_class = true
class_attribute :observers
def self.add_observer(observer)
observers << observer
logger.debug("Observer #{observer.name} added to #{self.name}")
end
def notify_observers(obj, event_name, *args)
observers && observers.each do |observer|
if observer.respond_to?(event_name)
begin
observer.public_send(event_name, obj, *args)
rescue Exception => e
logger.error("Error notifying observer #{observer.name}")
logger.error e.message
logger.error e.backtrace.join("\n")
end
end
end
end
상속에 대한 구성의 정신에서 위의 코드를 모듈에 배치하고 각 모델에서 혼합 할 수 있습니다.
이니셜 라이저는 옵저버를 등록합니다.
User.add_observer(NotificationSender)
User.add_observer(ProfilePictureCreator)
그런 다음 각 모델은 기본 ActiveRecord 콜백 외에도 자체 관찰 가능한 이벤트를 정의 할 수 있습니다. 예를 들어, 내 사용자 모델은 2 개의 이벤트를 노출합니다.
class User < Party411BaseModel
self.observers ||= []
after_commit :notify_observers, :on => :create
def signed_up_via_lunchwalla
self.account_source == ACCOUNT_SOURCES['LunchWalla']
end
def notify_observers
notify_observers(self, :new_user_created)
notify_observers(self, :new_lunchwalla_user_created) if self.signed_up_via_lunchwalla
end
end
해당 이벤트에 대한 알림을 수신하려는 관찰자는 (1) 이벤트를 노출하는 모델에 등록하고 (2) 이름이 이벤트와 일치하는 방법을 가지고 있으면됩니다. 예상 한대로 여러 명의 옵저버가 동일한 이벤트에 등록 할 수 있으며 (원래 질문의 두 번째 단락을 참조하여) 옵저버는 여러 모델의 이벤트를 감시 할 수 있습니다.
아래의 NotificationSender 및 ProfilePictureCreator 옵저버 클래스는 다양한 모델에 의해 노출되는 이벤트에 대한 메소드를 정의합니다.
NotificationSender
def new_user_created(user_id)
...
end
def new_invitation_created(invitation_id)
...
end
def new_event_created(event_id)
...
end
end
class ProfilePictureCreator
def new_lunchwalla_user_created(user_id)
...
end
def new_twitter_user_created(user_id)
...
end
end
한 가지주의 사항은 모든 모델에서 노출되는 모든 이벤트의 이름이 고유해야한다는 것입니다.