2010-02-10 2 views
1

Мы используем AASM в целом ряде наших моделей, но мы смотрим на упрощение моделей. Одна из вещей, которые мы хотели бы сделать, - это переместить все материалы Уведомления из моделей и в Наблюдатели.Захватывающие наблюдатели с событиями

Так, учитывая:

class ClarificationRequest < ActiveRecord::Base 
    include AASM 

    aasm_initial_state :open 

    # States 
    aasm_state :open 
    aasm_state :closed 

    # Events 
    aasm_event :close, :after => :notify_closed do transitions :to => :closed, :from => [:open,:replied], :guard => :can_close? end 
end 

Я попытался это, но не повезло:

class ClarificationRequestObserver < ActiveRecord::Observer 
    observe :clarification_request 

    def after_close 
    puts '############### message from observer!!!!!' 
    end 
end 

Как я могу переместить: notify_closed в качестве наблюдателя?

Thx!

.Karim

ответ

0

Чтобы быть честным, я думаю, что у вас было все в порядке. Имеет смысл использовать AASM-крючки для таких вещей. Таким образом, вы знаете, что он перешел в ОК, а затем вы отправили уведомление.

Вы можете посмотреть, как использовать активную запись в файле before_update, чтобы проверить, открыто ли state_was и теперь закрыто.

+0

Одна из основных проблем, с которыми мы сталкиваемся с этим подходом, состоит в том, что мы действительно хотим создавать события (тип модели аудита), которые также должны иметь current_user_id, и, насколько мне известно, нет простого или правильного способ включить это в Модели ... следовательно, наблюдатели? – khelal

+0

Хотя это может быть и не идеально, вы можете получить идентификатор пользователя следующим образом: В модели пользователя добавьте cattr_accessor: current_user. В контроллере приложения добавьте параметр before_filter, который вызывает def set_current_user. User.current_user = self.current_user – tsdbrown

1

Я ответил на ваш комментарий на GitHub прежде, я буду повторять его здесь, на всякий случай

class ClarificationRequest < ActiveRecord::Base 
    include AASM 

    aasm_initial_state :open 

    # States 
    aasm_state :open 
    aasm_state :closed 

    # Events 
    aasm_event :close, :after => :notify_closed do transitions :to => :closed, :from => [:open,:replied], :guard => :can_close? end 

    # Notify Observer 
    def notify_closed 
    notify :close # this will trigger after_close method call in ClarificationRequestObserver 
    # notify :closed # this will trigger after_closed method call in ClarificationRequestObserver 
    # notify :whatever # this will trigger after_whatever method call in ClarificationRequestObserver 
    end 
end 
+0

Это один трудолюбивый чувак. – Jaryl

+0

Спасибо за подсказку. Я бы добавил +1, но комментарии вводят в заблуждение. 'notify: close' фактически называет' ClarificationRequestObserver # close' (и ** не ** после #after_close) – averell

0

Я хотел бы сделать что-то вроде этого:

class ClarificationRequest < ActiveRecord::Base 
    include AASM 

    aasm_initial_state :open 

    # States 
    aasm_state :open 
    aasm_state :closed, :enter => :do_close 

    # Events 
    aasm_event :close do transitions :to => :closed, :from => [:open,:replied], :guard => :can_close? end 

    def recently_closed? 
    @recently_closed 
    end 
protected 
    def do_close 
    @recently_closed = true 
    end 

end 


class ClarificationRequestObserver < ActiveRecord::Observer 
    observe :clarification_request 

    def after_save(clarification_request) 
    puts '############### message from observer!!!!!' if clarification_request.recently_closed? 
    end 
end 

Вы должны также включать в себя наблюдатель в списке config.active_record.observers в config/environment.rb

Причина этого в том, что наблюдатель должен наблюдать за объектом. Активно уведомляя (и взаимодействуя) с наблюдателем от модели, вы предполагаете, что есть один доступный, который я не верю, что вы можете безопасно (видя, как наблюдатели обычно ведут себя в реальном мире). Независимо от того, интересуется ли это событием или нет, зависит от наблюдателя.