Вот простое решение.
Изменения:
- Нет необходимости проверять наличие
USER_KEY
.
- Попробуйте найти константу в модуле / классе получателя (в вашем случае это будет контроллер). Если он существует, используйте его, в противном случае используйте модуль / класс по умолчанию (для определения значения по умолчанию см. Ниже).
.
module Auth
USER_KEY = "user"
def authorize
user_key = self.class.const_defined?(:USER_KEY) ? self.class::USER_KEY : USER_KEY
user_id = session[user_key]
def
end
Объяснение
Поведение, которое вы видите, не является специфичным для rails, но связано с тем, где ruby ищет константы, если он явно не ограничен с помощью ::
(то, что я называю выше по умолчанию). Поиск констант осуществляется с использованием «лексической области текущего выполняемого кода». Это означает, что ruby сначала ищет константу в модуле (или классе) исполняемого кода, а затем перемещается наружу к каждому последующему включающему модулю (или классу), пока не найдет константу, определенную в этой области.
В вашем контроллере вы звоните authorize
. Но когда authorize
выполняется, текущий исполняемый код находится в Auth
. Так вот где константы ищутся. Если у Auth не было USER_KEY
, но у него есть включающий модуль, то будет использоваться включающий. Пример: * * тысяча двадцать-шесть
module Outer
USER_KEY = 'outer_key'
module Auth
# code here can access USER_KEY without specifying "Outer::"
# ...
end
end
Особый случай этого - среда исполнения верхнего уровня, которая рассматривается как принадлежащая классу Object
.
USER_KEY = 'top-level-key'
module Auth
# code here can access the top-level USER_KEY (which is actually Object::USER_KEY)
# ...
end
Одна ловушка - определение модуля или класса с помощью оператора определения объема (::
):
module Outer
USER_KEY = 'outer_key'
end
module Outer::Auth
# methods here won't be able to use USER_KEY,
# because Outer isn't lexically enclosing Auth.
# ...
end
Обратите внимание, что константа может быть определена намного позже, чем метод. Поиск происходит только при обращении к USER_KEY, так что это тоже работает:
module Auth
# don't define USER_KEY yet
# ...
end
# you can't call authorize here or you'll get an uninitialized constant error
Auth::USER_KEY = 'user'
# now you can call authorize.