Я пытаюсь реализовать и Authorization
модуль, потому что в настоящее время логика авторизации для определенного ресурса разделена на два или три разных места, и хотя я не уверен, что это лучший подход, по крайней мере, я думаюэто обеспечит некоторую инкапсуляцию.
Поскольку я проверяю несколько разных вещей
- Имеет ли пользователь правильную роль
- Являются ли ресурсы в правильном состояниидля обработки требуемого действия
- Имеет ли пользователь право выполнять требуемое действие на этом конкретном ресурсе
Итак, как вы можете видеть, есть несколько проверок, я неделая вид, что здесь все правильно, но это довольно близко к реальному случаю, поэтому я решил использовать что-то вроде Result Object , хотя на самом деле это не объект, а struct
, и я 'Я не использую Gem, но довольно простую пользовательскую реализацию.
Итак, часть моего Authorization
модуля такова:
module Authorization
Result = Struct.new(:successfull?, :error)
extend self
def read(user, resource, message: 'Permission denied')
can_read =
[
condition1,
condition2,
condition3
]
return Result.new(can_read.any?, can_read.any? ? nil : message))
end
Однако внутри этого Authorization
модуля IУ меня много методов, и некоторые из них проверяют read
внутренне так:
def assign(user, resource, message: 'Permission denied')
return read(user, resource) unless read(user, resource).successfull?
Result.new(true, nil)
end
Поэтому мой главный вопрос - как избежать этого двойного вызова read(user, resource)
.Я полагаю, что одним из вариантов было бы просто позвонить перед проверкой, например:
result = read(user, resource)
return result unless result.successfull?
Однако я довольно плохо знаком с Ruby
и подозреваю, что, возможно, есть более похожий на рубин способ сделать это.Просто чтобы как-то вставить это, присваивая результат из read
внутри проверки состояния ... Однако это просто дикое предположение.
И еще один вопрос, который возник, когда я писал это.В настоящее время, если я хочу отправить nil
для сообщения, когда авторизация проходит, я делаю это:
return Result.new(can_read.any?, can_read.any? ? nil : message))
, потому что message unless can_read.any?
выбрасывает и выдает ошибку, хотя я думал, что по умолчанию будет nil
.Итак, еще раз, есть ли какой-нибудь рубиновый способ сделать это?