Rails: как получить доступ к текущему контроллеру в Observer? - PullRequest
5 голосов
/ 15 ноября 2011

Мне нужно получить доступ к текущему контроллеру или прошить уведомление от метода наблюдателя.

class SomeObserver < ActiveRecord::Observer
    observe :some_model
    cattr_accessor :current_controller

    def after_create(record)
        ...
        current_controller.flash[:notice] = "Some message!"
    end
end

class ApplicationController < ActionController::Base
    before_filter do
        SomeObserver.current_controller = self
    end
    ...
end

Ответы [ 4 ]

4 голосов
/ 18 сентября 2012

Как уже говорили другие, доступ к контроллеру от наблюдателя несколько нарушает принцип MVC. Также данные ответы подходят для вашего конкретного случая использования.

Но если вам нужно более общее решение, вы можете попытаться адаптировать способ работы Rails Sweepers .

Подметальные машины являются обычными наблюдателями, но они предоставляют доступ к контроллеру, , если наблюдатель вызывается из действия контроллера.

Это достигается за счет использования подметальной машины как наблюдателя и контроллера фильтра одновременно, что легко возможно, поскольку наблюдатели являются синглетонами (то есть включают Singleton модуль)

В двух словах, вы должны сделать это:

  1. Создайте своего наблюдателя как обычно.
  2. Добавьте экземпляр singleton как around_filter к вашему контроллеру:

    class ApplicationController < ActionController::Base
      around_filter MyObserver.instance #, only: [...]
    end
    
  3. Добавьте методы фильтра вашему наблюдателю:

    attr_accessor :controller
    
    def before(controller)
      self.controller = controller
      true #Don't forget this!
    end
    
    def after(controller)
      self.controller = nil
    end
    

Теперь вы можете получить доступ к контроллеру с помощью обратных вызовов наблюдателя. Однако controller равно nil, если наблюдатель был запущен вне действия контроллера.

2 голосов
/ 15 ноября 2011

Доступ к контроллеру из Observer нарушает схему MVC. Способ сделать это без нарушения MVC - назначить flash[:notice] из контроллера после вызова SomeModel.create().

1 голос
/ 15 ноября 2011

Почему в наблюдателе? Вы должны поместить назначение вспышки в свой контроллер, причина в том, что вспышка относится к уровню обзора.

С другой стороны

Создайте вспомогательный метод в вашем файле application_helper, который проверяет flash и diplay.

def show_flash
[:notice, :error, :warning].collect do |key|
  content_tag(:div, flash[key], :id => key, :class => "flash flash_#{key}") unless   flash[key].blank?
end.join
end

Тогда в вашем макете просто добавьте

<% show_flash %>

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

и теперь вы можете просто использовать

flash[:notice] = "Some message!"
0 голосов
/ 15 ноября 2011

В Rails нет связи между наблюдателями и контролерами, и я боюсь, что вы не достигнете своей цели стандартным способом.Однако я предлагаю использовать темы для достижения этой цели.

...