Ruby on Rails - переменная контроллера доступа из модели - PullRequest
19 голосов
/ 10 марта 2010

Я пытаюсь получить доступ к переменной экземпляра, которая установлена ​​в контроллере в модели. Контроллер - это контроллер продуктов, а модель - модель продуктов. Переменная instance является экземпляром другой модели, называемой account.

Переменная экземпляра: @current_account

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

Спасибо

Eef

Ответы [ 5 ]

46 голосов
/ 10 марта 2010

Обычно вы не должны пытаться получить доступ к контроллеру из модели, если я не буду вдаваться в подробности.

Я решил похожую проблему следующим образом:

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

8 голосов
/ 06 апреля 2012

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Следующий код нарушает соглашения 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]

5 голосов
/ 12 марта 2010

Если вам нужно для доступа к переменной контроллера из модели, это обычно означает, что ваш проект неправильный, потому что контроллер служит мостом между представлением и моделью (по крайней мере, в Rails), контроллер получает информацию от моделей, Модели не должны ничего знать о контроллерах, но если вы все равно хотите это сделать, вы можете сделать это так, как сказал Джим, но я бы предпочел:

 class << self

    attr_accessor :current

 end

вместо

cattr_accessor :current

Вы можете понять, почему здесь => cattr_accessor не работает должным образом

2 голосов
/ 07 августа 2010

Я не могу комментировать напрямую, поэтому я опубликую здесь: принятый ответ не кажется правильным. Как отмечает @vise, переменные класса распределяются между запросами. Поэтому, если для всего приложения не существует только одной текущей учетной записи, она не будет работать должным образом.

Для получения дополнительной информации см. Принятый ответ @molf здесь: Является ли Rails ничего общего или могут ли отдельные запросы обращаться к одним и тем же переменным времени выполнения?

1 голос
/ 10 марта 2010

Я не уверен, правильно ли я понял вопрос, но сделаю удар.

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

...