Это довольно легко сделать. Вы можете реализовать предложение Ориона, но вы также можете реализовать более широкую технику, показанную ниже, которая дает вам доступ к текущему контроллеру из любой модели и для любой цели, для которой вы решили нарушить разделение MVC (например, возиться с фрагментным кешем, получая доступ к * 1001). *, генерация путей / URL и т. д.)
Чтобы получить доступ к контроллеру текущего запроса (если есть) из любой модель , добавьте следующее к environment.rb
или, что гораздо предпочтительнее, , для нового плагина (например, создайте vendor/plugins/controller_from_model/init.rb
, содержащий код ниже):
module ActiveRecord
class Base
protected
def self.thread_safe_current_controller #:nodoc:
Thread.current[:current_controller]
end
def self.thread_safe_current_controller=(controller) #:nodoc:
Thread.current[:current_controller] = controller
end
# pick up the correct current_controller version
# from @@allow_concurrency
if @@allow_concurrency
alias_method :current_controller, :thread_safe_current_controller
alias_method :current_controller=, :thread_safe_current_controller=
else
cattr_accessor :current_controller
end
end
end
Затем, в app/controllers/application.rb
,
class ApplicationController < ActionController::Base
before_filter { |controller|
# all models in this thread/process refer to this controller
# while processing this request
ActiveRecord::Base.current_controller = controller
}
...
Тогда от любой модели ,
if controller = ActiveRecord::Base.current_controller
# called from within a user request
else
# no controller is available, didn't get here from a request - maybe irb?
fi
Во всяком случае, в вашем конкретном случае вы можете захотеть внедрить код в ваших различных ActiveRecord::Base
потомков, когда загружаются соответствующие классы контроллера, так что фактический код с поддержкой контроллера все еще находится в app/controllers/*.rb
, но это не обязательно сделайте это, чтобы получить что-то функциональное (хотя и некрасивое и сложное в обслуживании.)
Веселись!