Я работаю над рубином на приложении направляющих. Для контроллера сессий я хочу использовать случай, чтобы проверить, заблокирована ли учетная запись пользователя или запрещена. Я пытаюсь использовать объект класса как случай и использование, когда проверить атрибуты.
Например,
user = Profile.find(1)
case user
when user.ban
redirect_to()
when user.lock
redirect_to()
else
redirect_to()
end
Единственная проблема, это не работает.
То, что действительно работает, является этим:
case user.ban
when true
redirect_to()
else
redirect_to()
end
Совет относительно того, как я могу пойти о проверке, если пользовательский объект запрещается или заблокировал использование переключателя?
Спасибо
Создайте метод user.status , который возвращает состояние пользователя, тогда вы можете сделать это:
user = Profile.find(1)
case user.status
when "banned"
redirect_to()
when "locked"
redirect_to()
else
redirect_to()
end
Просто не учитывайте пользователя
:
user = Profile.find(1)
case
when user.ban
redirect_to
when user.lock
redirect_to
else
redirect_to
end
В Ruby есть две формы выражения case
. В приведенной выше форме он просто выполняет первую ветвь, которая возвращает истинное значение (т.е. все, кроме nil
или false
).
Другая форма
case foo
when bar
baz
end
эквивалентна
if bar === foo
baz
end
Лол, мне нравится ответ Амадана. И если вам действительно нужен оператор case, вам, вероятно, следует делать то, что сказал Зепплок (хотя можно рассматривать символы вместо строк), но в зависимости от вашего варианта использования вам нужно решение, основанное на операторах if, как у Салила.
В любом случае, я подумал, что добавлю и тоже повеселюсь ^ _ ^ Вот решение, которое будет работать с тем, что вы сказали, оно создает объекты, которые отвечают на === (какие операторы case используют), затем они вызывают интересующий метод (блокировка или запрет) и возвращают его. Вам, вероятно, следует поместить их в какую-то конфигурацию или инициализатор или иным образом сохранить результаты после первого вызова, чтобы сохранить производительность (ваше приложение должно создать эти объекты только один раз)
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
Примечание: я не защищаю это решение, потому что оно нарушает инкапсуляцию. Запрещенное должно быть определено и использовано для вашего пользователя, но чтобы это работало, оно должно быть определено в охватывающей области. Я в основном говорю об этом для развлечения :)
вы можете сделать, как сказал Зепплок. Но для данного примера лучший способ (просто пример)
action_name = (user.ban)? "ban" : ( (user.lock)? "lock" : "default")
redirect_to(:action => action_name)
@Brian, идея случая переключения заключается в том, что у вас есть переменная, которая принимает динамическое значение и сравнивает его с парой постоянных наборов значений. В написанном вами фрагменте кода операторы case содержат динамические значения, такие как user.ban, которые зависят от самой переменной, которую вы пытаетесь проверить. Правильный способ использования корпуса переключателя продемонстрировал @Zepplock.
Мне нравится ответ @Salil; однако, если вам действительно нравится case
, вы можете сделать это:
case true
when user.ban
redirect_to()
when user.lock
redirect_to()
else
redirect_to()
end
UPDATE Йорг сказал, что это тоже работает, и он прав! Дайте ему несколько голосов за его ответ! (Как и я)
case
when user.ban
redirect_to()
when user.lock
redirect_to()
else
redirect_to()
end
ОБНОВЛЕНИЕ 2012 Теперь это работает:
case user
when lambda(&:ban)
redirect_to()
when lambda(&:lock)
redirect_to()
else
redirect_to()
end
end