Рассмотрим этот кодRails: включить модуль, но сохранить имя модуля?
module Auth
def sign_in(user)
#some stuff
session[:user_id] = user.id
end
end
Теперь я хочу, чтобы включить это в мой контроллер приложения.
ApplicationController < ActionController::Base
include Auth
end
Это делает метод sign_in
во всех моих контроллеров. Теперь, чтобы понять, что это не действие контроллера, я хотел бы сохранить имя, так что мои контроллеры чтения
def sign_user_in
# Some stuff
Auth.sign_in(@user)
end
Это, очевидно, не работает, потому что Rails будет искать метод класса в Auth модуль. Итак, вопрос в том ... Можно ли включить модуль в контроллер, сохранить его имя или пространство имен, но все же получить доступ к той же области, что и контроллер? (в этом случае переменная сеанса).
До сих пор наименее плохой способ я придумал, это остановить, включая модуль и в ApplicationController и вместо того, чтобы передать экземпляр контроллера приложения вместе при вызове метода аутентификации, как это:
def current_user(controller)
User.find(controller.session[:user_id])
end
Вызов этого метода от контроллера с использованием self
в качестве аргумента.
ИМО, которая была бы худшим из обоих миров: все опасности воздействия с ни одно из преимуществ одного пространства имен. –
Преимущества для одного пространства имен? О чем ты говоришь? У меня есть набор методов, которые работают с экземплярами контроллера, но я не хочу, чтобы мой контроллер приложений увеличивался. Кроме того, мне нравится контекст метода, который предоставляет константа. Я думаю, что это улучшает читаемость. Я знаю, что я могу использовать префиксы вместо этого и делать 'auth_method_name', но я действительно думаю, что' Auth.method_name' выглядит лучше. JavaScript предлагает это благодаря контексту выполнения, но как это делает Ruby? Если бы я подумал, что есть что-то полезное в отношении «single namespacing», я бы программировал PHP. –
TL; DR. Вы явно сказали, что хотите получить доступ к 'session' изнутри mixin, но только в mixin, а не в контроллере. Опасности воздействия, без преимуществ. Если вы собираетесь разделить проблемы, * отделите их * и используйте служебный объект. Простое перемещение функциональности в mixin не делает контроллер менее жирным: переместите его в изолированный класс * does *. –