Ruby on Rails Case / Switch.Как сопоставить с объектом? - PullRequest
14 голосов
/ 03 июля 2010

Я работаю над приложением 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

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

Спасибо

Ответы [ 6 ]

25 голосов
/ 03 июля 2010

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

user = Profile.find(1)
case user.status
when "banned"
  redirect_to()
when "locked"
  redirect_to()
else
  redirect_to()
end
14 голосов
/ 03 июля 2010

Мне нравится ответ @ Салила;однако, если вам действительно нравится case, вы можете сделать это:

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

ОБНОВЛЕНИЕ Йорг сказал, что это тоже работает, и он прав!Дайте ему несколько голосов на его ответ!(Как и я)

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
7 голосов
/ 03 июля 2010

Просто пропустите user:

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
2 голосов
/ 03 июля 2010

Лол, я люблю ответ Амадана.И если вы действительно хотите использовать оператор case, вы, вероятно, должны делать то, что сказал Zepplock (хотя вместо строк могут рассматриваться символы), но в зависимости от вашего варианта использования вам нужно решение на основе более if-оператора, например, Salil.

Во всяком случае, подумал, что я бы добавил и тоже повеселился ^ _ ^ Вот решение, которое будет работать с тем, что вы сказали, оно создает объекты, которые отвечают на === (какие выражения используют), затем онивызовите метод интереса (блокировка или запрет) и верните его.Вам, вероятно, следует поместить их в какой-либо конфигурационный файл или инициализатор или иным образом сохранить результаты после первого вызова, чтобы сохранить производительность (ваше приложение должно создавать эти объекты только один раз)

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

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

0 голосов
/ 03 июля 2010

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

0 голосов
/ 03 июля 2010

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

action_name = (user.ban)? "ban" : ( (user.lock)?  "lock" : "default")
redirect_to(:action => action_name)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...