2010-07-03 9 views
9

Estoy trabajando en una aplicación Ruby on Rails. Para un controlador de sesión, quiero usar un caso para verificar si la cuenta de un usuario está bloqueada o prohibida. Intento usar el objeto de una clase como el caso y usar cuándo verificar los atributos.Funda/interruptor Ruby on Rails. ¿Cómo hacer coincidir el objeto?

Por ejemplo,

user = Profile.find(1) 
case user 
when user.ban 
    redirect_to() 
when user.lock 
    redirect_to() 
else 
    redirect_to() 
end 

El único problema es que no funciona.

Lo que funciona es la siguiente:

case user.ban 
when true 
    redirect_to() 
else 
    redirect_to() 
end 

Cualquier consejo sobre cómo puedo ir sobre cómo comprobar si un objeto de usuario está prohibido o bloqueado con un interruptor?

Gracias

Respuesta

19

hacer una método user.status que devuelve un estado de un usuario, entonces usted puede hacer esto:

user = Profile.find(1) 
case user.status 
when "banned" 
    redirect_to() 
when "locked" 
    redirect_to() 
else 
    redirect_to() 
end 
+0

Gracias por todas las respuestas. Encontré la respuesta de Zepplock la más útil para mi aplicación. La única diferencia es que usé símbolos en el método y el caso. Aquí está el método que escribí: estado def si self.ban retorno: prohibición final si self.lock retorno: bloquear final final – Brian

+0

@ Brian: Sólo para Rubify un poco - si una función devuelve un valor lógico, es buena forma nombrarlo con un signo de interrogación. Además, aunque los modificadores posteriores se pueden abusar y perjudicar la legibilidad, en este caso creo que trabajan para mejorarlo: 'def status; retorno: prohibido si está prohibido ?; return: bloqueado si está bloqueado? fin' – Amadan

0

que puede hacer como dijo Zepplock. Pero para un ejemplo dado la siguiente es la mejor manera (solo un ejemplo)

action_name = (user.ban)? "ban" : ((user.lock)? "lock" : "default") 
redirect_to(:action => action_name) 
13

Me gusta @ Salil's answer; sin embargo, si te gusta mucho case, usted puede hacer esto:

case true 
    when user.ban 
    redirect_to() 
    when user.lock 
    redirect_to() 
    else 
    redirect_to() 
end 

ACTUALIZACIÓN Jörg dijo que esto funciona también, y tiene razón! ¡Dale algunos votos sobre su respuesta! (Como se me)

case 
    when user.ban 
    redirect_to() 
    when user.lock 
    redirect_to() 
    else 
    redirect_to() 
end 

ACTUALIZACIÓN 2012 Esto funciona ahora:

case user 
    when lambda(&:ban) 
    redirect_to() 
    when lambda(&:lock) 
    redirect_to() 
    else 
    redirect_to() 
    end 
end 
+0

+1 para nunca pensar en usar verdadero como condición de caso. – Salil

+0

Supongo que el orden de when s es bastante importante, ¿no? De todos modos, +1 para una idea tan increíble. –

+3

Esto es innecesariamente complicado. La razón por la que esto funciona es que 'true === true' es truish. Pero la otra forma de la expresión 'case ', es decir, simplemente dejando fuera el' verdadero' en total, ya hace lo mismo de todos modos. –

0

@ Brian, la idea de una caja de conmutación es que tiene una variable que acepta un valor dinámico y comprueba si se contra un par de conjuntos de valores constantes. En la pieza de código que escribió, las declaraciones de casos contienen valores dinámicos como user.ban que depende de la variable en sí que está intentando verificar. La forma correcta de usar una caja de conmutadores es cómo demostró @Zepplock.

2

Lol, me encanta la respuesta de Amadan. Y si realmente quiere una declaración de caso, probablemente debería estar haciendo lo que dijo Zepplock (aunque podría considerar símbolos en lugar de cadenas), pero en función de su caso de uso, quiere una solución más basada en enunciados si, como la de Salil.

De todos modos, pensé en tirar y divertirme también^_^ Aquí hay una solución que funcionará con lo que dices, crea objetos que responden a === (lo que usan los enunciados), luego invocan el método de interés (bloqueo o prohibición) y lo devuelven. Probablemente les debe poner en algún tipo de configuración o de inicialización, o de otro modo almacenar los resultados después de la primera invocación, a fin de salvar el rendimiento (su aplicación sólo necesita crear estos objetos una vez)

user = Class.new do 
    def ban() true end 
    def lock() true end 
end.new 

def banned? 
    ban_checker = Object.new 
    def ban_checker.===(user) user.ban end 
    ban_checker 
end 

def locked? 
    lock_checker = Object.new 
    def lock_checker.===(user) user.lock end 
    lock_checker 
end 

case user 
when banned? 
    puts 'banned' 
when locked? 
    puts 'locked' 
else 
    puts 'default' 
end 

Nota: I No defiendo esta solución porque viola la encapsulación. Prohibido debe definirse y usarse en su usuario, pero para que esto funcione, debe definirse en el alcance adjunto.Yo sobre todo plantear esto por diversión :)

7

acaba de salir de la user:

user = Profile.find(1) 
case 
when user.ban 
    redirect_to 
when user.lock 
    redirect_to 
else 
    redirect_to 
end 

En Ruby, hay dos formas de la expresión case. En el formulario anterior, simplemente ejecuta la primera rama que evalúa un valor de truish (es decir, cualquier cosa excepto nil o false).

La otra forma

case foo 
when bar 
    baz 
end 

es equivalente a

if bar === foo 
    baz 
end