jueves, 1 de octubre de 2009

Validando en rails cuando necesitas acceder a current_user

Estoy en medio de un proyecto con acts_as_authenticated y me he encontrado con el problema siguiente:

A la hora de validar un modelo, necesito comprobar unos atributos del usuario actual. Es decir, necesito acceder a los atributos de current_user.

Sin embargo, dicha variable no está disponible en el modelo. Así que buscando en google encontré esta discusión, que me dio una posible solución.

El resumen es el siguiente:

Hay que crear un atributo de clase thread en User (o en la clase que tengamos definidas para almacenar los usuarios) que me devolverá el current_user:

class User < ActiveRecord::Base
  cattr_accessor :current_user
  def self.current_user
    Thread.current[:user]
  end

  def self.current_user=(user)
    Thread.current[:user] = user
  end

end

Luego, en application_controller, para que esté disponible siempre, se define un before_filter

class ApplicationController < ActionController::Base
  before_filter :set_current_user
private
  def set_current_user
    User.current_user = current_user
  end
end

De esta forma, se asigna al atributo de clase User.current_user, la variable current_user. Ahora basta con llamar a User.current_user para poder acceder a la información que estábamos buscando.

class Project < ActiveRecord::Base
  validate :my_validation
private
  def my_validation
    errors.add(:validating_attribute, 'validating_attribute_error') unless User.current_user.my_method
  end
end



"Si la industria automovilística hubiera seguido el mismo desarrollo que los ordenadores, un Rolls-Royce costaría hoy 100 dólares, circularía un millón de millas con 3,7 litros y explotaría una vez al año, eliminando a todo el que estuviera dentro en ese momento"
-- Robert X. Cringely

3 comentarios:

  1. Enhorabuena por tu nuevo blog ;-)

    Y de paso para seguir modas, te estreno los comentarios :-D

    ResponderEliminar
  2. Para mí que un modelo no debería de saber nada de quién es current_user, de si estás logado o no, etc.

    ResponderEliminar
  3. Para mí tampoco ;-). Lo suyo sería controlarlo en su controller (valga la "rebuznancia"), que para eso está, pero me apetecía probar qué tal funcionaba este método, porque pensé que podía serme útil en algún momento.

    ResponderEliminar