Rails 3 devise, el usuario actual no es accesible en un Modelo?
En mi proyecto.modelo rb, estoy tratando de crear un ámbito con una variable dinámica:
scope :instanceprojects, lambda {
where("projects.instance_id = ?", current_user.instance_id)
}
Obtengo el siguiente error:
undefined local variable or method `current_user' for #<Class:0x102fe3af0>
Donde en el controlador puedo acceder current_user.instance_id
... ¿Hay alguna razón por la que el modelo no puede acceder a él y una manera de obtener acceso? Además, ¿es este el lugar correcto para crear un ámbito como el anterior, o pertenece al controlador?
4 answers
Esto no tiene mucho sentido, como ya señalaste. El current_user no pertenece a la lógica del modelo en absoluto, debe ser manejado en el nivel del controlador.
Pero aún puede crear un ámbito como ese, simplemente pase el parámetro desde el controlador:
scope :instanceprojects, lambda { |user|
where("projects.instance_id = ?", user.instance_id)
}
Ahora puedes llamarlo en el controlador:
Model.instanceprojects(current_user)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-24 08:39:23
La respuesta ya aceptada proporciona una manera realmente correcta de lograr esto.
Pero aquí está la versión segura de User.current_user
truco.
class User
class << self
def current_user=(user)
Thread.current[:current_user] = user
end
def current_user
Thread.current[:current_user]
end
end
end
class ApplicationController
before_filter :set_current_user
def set_current_user
User.current_user = current_user
end
end
Esto funciona como se espera, sin embargo, se puede considerar sucio, porque básicamente definimos una variable global aquí.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-21 10:10:42
Ryan Bates presenta una forma bastante segura de implementar este tipo de estrategia en este railscast
Este es un episodio pagado (¡no me votes!) pero puedes buscar el código fuente de forma gratuita
Aquí crea un método current_tenant
, pero usted podría sustituir fácilmente current_user
en su lugar.
Aquí están los bits clave de código...
#application_controller.rb
around_filter :scope_current_tenant
private
def current_tenant
Tenant.find_by_subdomain! request.subdomain
end
helper_method :current_tenant
def scope_current_tenant
Tenant.current_id = current_tenant.id
yield
ensure
Tenant.current_id = nil
end
#models/tenant.rb
def self.current_id=(id)
Thread.current[:tenant_id] = id
end
def self.current_id
Thread.current[:tenant_id]
end
Entonces en el modelo se puede hacer algo como...
default_scope { where(tenant_id: Tenant.current_id) }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-21 17:27:17
No es necesario utilizar ámbitos. Si ha establecido las asociaciones apropiadas en los modelos, el siguiente fragmento de código colocado en el controlador debería hacer el truco:
@projects = current_user.instance.projects
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-18 19:32:50