Ruby on Rails - переменная контроллера доступа из модели
Я пытаюсь получить доступ к переменной экземпляра, которая установлена в контроллере в модели. Контроллер - это контроллер продуктов, а модель - модель продуктов. Переменная instance является экземпляром другой модели, называемой account.
Переменная экземпляра @current_account
Когда я запускаю код ничего не происходит, я не получаю сообщение об ошибке. Кто-нибудь знает, где я могу найти что-то прочитать о переменных экземпляра доступа, установленных в контроллере из модели?
Спасибо
Eef
5 ответов
Вы не должны обычно пытаться получить доступ к контроллеру из модели для серьезных проблем, в которые я не буду вдаваться.
Я решил похожую проблему следующим образом:
class Account < ActiveRecord::Base
cattr_accessor :current
end
class ApplicationController < ActionController::Base
before_filter :set_current_account
def set_current_account
# set @current_account from session data here
Account.current = @current_account
end
end
Затем просто получить доступ к текущей учетной записи с Account.current
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Следующий код нарушает соглашения MVC, который сказал...
Использование атрибутов класса может привести к проблемам безопасности потоков. Я бы использовал Thread.current + around_filter для хранения данных, связанных с контроллером, на уровне потока и гарантировал, что они очищаются непосредственно перед завершением запроса:
class ApplicationController < ActionController::Base
around_filter :wrap_with_hack
def wrap_with_hack
# We could do this (greener solution):
# http://coderrr.wordpress.com/2008/04/10/lets-stop-polluting-the-threadcurrent-hash/
# ... but for simplicity sake:
Thread.current[:controller] = self
begin
yield
ensure
# Prevent cross request access if thread is reused later
Thread.current[:controller] = nil
end
end
end
Теперь текущий экземпляр контроллера будет доступен глобально во время обработки запроса через Thread.current[:controller]
Если вам нужен доступ к переменной контроллера из модели, это обычно означает, что ваш проект неправильный, потому что контроллер служит мостом между представлением и моделью (по крайней мере, в Rails), контроллер получает информацию от моделей, модели не должны ничего знать о контроллерах, но если вы хотите сделать это в любом случае, вы можете сделать это так, как сказал Джим, но я бы лучше сделал:
class << self
attr_accessor :current
end
вместо
cattr_accessor: текущий
Вы можете понять, почему здесь => cattr_accessor не работает должным образом
Я не могу комментировать напрямую, поэтому я опубликую здесь: принятый ответ не кажется правильным. Как отмечает @vise, переменные класса распределяются между запросами. Поэтому, если для всего приложения не существует только одной текущей учетной записи, она не будет работать так, как ожидалось.
Для получения дополнительной информации см. Принятый ответ @molf здесь: является ли Rails общим ресурсом или могут ли отдельные запросы обращаться к одним и тем же переменным времени выполнения?
Я не уверен, правильно ли я понял вопрос, но я сделаю удар.
Я думаю, что если вам нужен доступ к переменной экземпляра контроллера из модели, то вам нужно либо сделать ее атрибутом в модели, либо перенести свою логику в другой контроллер класса, а не в модель.