Случай/Переключатель Ruby on Rails. Как соответствовать против объекта?

Я работаю над рубином на приложении направляющих. Для контроллера сессий я хочу использовать случай, чтобы проверить, заблокирована ли учетная запись пользователя или запрещена. Я пытаюсь использовать объект класса как случай и использование, когда проверить атрибуты.

Например,

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

Совет относительно того, как я могу пойти о проверке, если пользовательский объект запрещается или заблокировал использование переключателя?

Спасибо

14
задан Mohit Jain 21 July 2010 в 09:37
поделиться

6 ответов

Создайте метод user.status , который возвращает состояние пользователя, тогда вы можете сделать это:

user = Profile.find(1)
case user.status
when "banned"
  redirect_to()
when "locked"
  redirect_to()
else
  redirect_to()
end
25
ответ дан 1 December 2019 в 06:23
поделиться

Просто не учитывайте пользователя :

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
7
ответ дан 1 December 2019 в 06:23
поделиться

Лол, мне нравится ответ Амадана. И если вам действительно нужен оператор 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

Примечание: я не защищаю это решение, потому что оно нарушает инкапсуляцию. Запрещенное должно быть определено и использовано для вашего пользователя, но чтобы это работало, оно должно быть определено в охватывающей области. Я в основном говорю об этом для развлечения :)

2
ответ дан 1 December 2019 в 06:23
поделиться

вы можете сделать, как сказал Зепплок. Но для данного примера лучший способ (просто пример)

action_name = (user.ban)? "ban" : ( (user.lock)?  "lock" : "default")
redirect_to(:action => action_name)
0
ответ дан 1 December 2019 в 06:23
поделиться

@Brian, идея случая переключения заключается в том, что у вас есть переменная, которая принимает динамическое значение и сравнивает его с парой постоянных наборов значений. В написанном вами фрагменте кода операторы case содержат динамические значения, такие как user.ban, которые зависят от самой переменной, которую вы пытаетесь проверить. Правильный способ использования корпуса переключателя продемонстрировал @Zepplock.

0
ответ дан 1 December 2019 в 06:23
поделиться

Мне нравится ответ @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
14
ответ дан 1 December 2019 в 06:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: