2015-03-30 3 views
0

У меня есть машина состояния, в приложении Rails (с ActiveRecord), которое определяется с помощью AASM и имеет много обратных вызовов. Некоторые из этих обратных вызовов содержат повторяющийся код. Например, при каждом изменении состояния нам необходимо создать и сохранить запись и отправить почту.Как сделать общий обратный вызов для любого «события» в AASM

event :revision, after: :revision_event_callback do 
    # ... 
end 

event :basic_submit, after: :basic_submit_event_callback do 
    # ... 
end 

event :approve, after: :approve_event_callback do 
    # ... 
end 

def revision_event_callback 
    OrderStatusMailer.status_change_report(self, :revision) 
    state_changes.build(transition: :revision) 
end 

def basic_submit_event_callback 
    OrderStatusMailer.status_change_report(self, :basic_submit) 
    state_changes.build(transition: :basic_submit) 
    # ... 
    # basic_submit-specific events 
end 

def approve_event_callback 
    OrderStatusMailer.status_change_report(self, :approve) 
    state_changes.build(transition: :approve) 
end 

Intead, я хотел бы иметь один общий обратный вызов, и для тех событий, которые нуждаются в этом, определенном в дополнении.

def event_callback(event_name) 
    OrderStatusMailer.status_change_report(self, event_name) 
    state_changes.build(transition: event_name) 
end 

def basic_submit_event_callback 
    # basic_submit-specific events 
end 

Возможно ли это вообще? И, что очень важно: как бы этот код имел доступ к названию события, которое было вызвано?

ответ

0

Возможно. Вы можете - в любой обратный вызов, как: после - запросить текущее событие, которое получил срабатывает, как это:

def event_callback 
    event_name = aasm.current_event # e.g. :revision or :revision! 
    OrderStatusMailer.status_change_report(self, event_name) 
    state_changes.build(transition: event_name) 
end 
+0

И это 'event_callback' магический метод, который будет добавлен к Колбек-цепи по умолчанию? Или мне еще нужно добавить его как 'after:: event_callback' в объявлениях-событиях? – berkes

+0

Нет, это ваш метод сверху. Вам все равно нужно объявить его следующим: после обратного вызова (с использованием события: ревизия, после:: event_callback do ...) – alto

0

Как об этом.

after_all_events : event_callback 

, а затем определить метод

def event_callback(*args) 
    # do stuff here 
    after_callback = "after_#{current_event}" 
    send(callback, *args) if respond_to?(callback) 
end