2010-03-10 27 views
19

Estoy intentando acceder a una variable de instancia que está configurada en el controlador del modelo. El controlador es el controlador de productos y el modelo es el modelo de productos. La variable de instancia es una instancia de otro modelo llamado cuenta.Ruby on Rails - Variable del controlador de acceso del modelo

La variable de instancia es @current_account

Cuando ejecuto el código no pasa nada, no me sale un error. ¿Alguien sabe dónde puedo encontrar algo leído sobre variables de instancias de acceso establecidas en el controlador desde el modelo?

Gracias

Eef

+0

¿Está intentando acceder a la variable @current_account en un modelo? La variable @current_account se está configurando en un controlador? – Steve

Respuesta

46

Por lo general, no debe intentar acceder al controlador desde el modelo en busca de problemas que no abordaré.

me resolvió un problema similar, así:

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 

A continuación, sólo tener acceso a la cuenta corriente con Account.current

+11

¿Las variables de clase no están compartidas en todas las solicitudes? – vise

+0

No entiendo cómo obtener el valor de la variable del: símbolo actual en el modelo? Intenté Account.actual y actual. – djburdick

+0

¿Cuál es la diferencia entre 'cattr_accessor' y' attr_accessor'? – user94154

1

no estoy seguro si entiendo la pregunta exactamente, pero voy a tomar una puñalada.

Creo que si necesita acceder a una variable de instancia del controlador desde el modelo, entonces necesita convertirlo en un atributo en el modelo, o mover su lógica al otro controlador de clase, no al modelo.

5

Si necesidad acceder a una variable de control de un modelo que por lo general significa que su diseño es mal porque un controlador sirve como puente entre la vista y el modelo (al menos en Rails), el controlador obtiene información de los modelos, los modelos no deberían saber nada sobre los controladores, pero si quieres hacerlo de todos modos puedes hacerlo tal como dijo jeem, pero prefiero hacer:

class << self 

    attr_accessor :current 

end 

en lugar de

cattr_accessor :current

se puede ver por qué aquí =>cattr_accessor doesn't work as it should

+0

Esto no es mucho mejor porque esto todavía se comparte entre las solicitudes, por no hablar de la seguridad de las secuencias. Debe ser un atributo en una _instancia de usuario o, de lo contrario, debe pasarlo a los métodos que necesitan conocerlo. – gtd

2

que no puedo comentar directamente, por lo que voy a publicar aquí: la respuesta aceptada no parece ser correcto. Como notas @vise, las variables de clase se comparten entre las solicitudes. Entonces, a menos que haya solo una cuenta actual para toda la aplicación, esto no se comportará como se espera.

Para más información, véase la respuesta aceptada por @molf aquí: Is Rails shared-nothing or can separate requests access the same runtime variables?

8

AVISO: El siguiente código rompe convenciones MVC, que dijo ...

El uso de atributos de clase, probablemente, puede conducir a hilo de seguridad cuestiones. Me gustaría utilizar Thread.current + around_filter a los datos relacionados controlador de tienda a nivel de hilo, y asegurarse de que se limpia justo antes de la solicitud termina:

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 

Ahora la instancia actual controlador habrá disponible globaly durante el procesamiento de la solicitud a través Thread.current [: controller]

+0

Hola @ibaixas gracias por esto. ¿Pero puede explicar cómo el atributo de clase conduce a un problema de seguridad de subprocesos? Soy un novato Y este problema también está presente en Rails 4 – Akshat

+1

Las variables de clase se comparten entre subprocesos. Esto significa que cuando se usa un servidor de aplicaciones multiproceso como puma, diferentes hilos que manejan diferentes solicitudes almacenan la instancia del controlador en la misma variable, sobrescribiéndose entre sí. Al utilizar el hash Thread.current, se asegura de que la variable solo esté configurada por el hilo actual. Perdón por el retraso de (2 años) ... – ibaixas

Cuestiones relacionadas