SessionsHelper в railstutorial.org: должны ли помощники быть универсальными модулями для кода, не необходимого в представлениях?
railstutorial.org есть предложение, которое кажется мне немного странным.
class ApplicationController < ActionController::Base
protect_from_forgery
include SessionsHelper
end
на include SessionsHelper
делает доступными методами от ApplicationController
, да, но это делает их доступными в любом виде, а также. Я понимаю, что аутентификация / авторизация является сквозной, но действительно ли это лучшее место?
это кажется мне потенциально слишком широким. Ввод кода, который реализует, скажем,before_filter
который условно перенаправляет (как railstutorial.org пример) в модуле, который чаще всего содержит помощники просмотра, кажется удивительным.
не будет ли функциональность, строго необходимая в представлениях, лучше помещаться в ApplicationController или в другом месте?
или я просто слишком много думаю об этом?
4 ответов
действительно, ваше чувство правильно.
Я бы реализовал это наоборот: добавьте функции sign_in
и current_user
до ApplicationController
(или, если вы действительно хотите, чтобы: в отдельном модуле определена в lib
и включить его), а затем убедитесь, что current_user
метод доступен в виде.
короче:
class ApplicationController
helper_method :current_user
def sign_in
end
def current_user
@current_user ||= user_from_remember_token
end
end
конечно, если у вас есть много кода для размещения в вашем ApplicationController
это может стать грязным. В этом случае я бы создал файл lib\session_management.rb
:
module SessionManagement
def self.included(base)
base.helper_method :current_user
end
def sign_in
..
end
def current_user
..
end
end
и внутри вашего контроллера вы можете просто написать:
class ApplicationController
include SessionManagement
end
Они Кажется использовать (подлое) преимущество того факта, что в Rails помощники-это просто модули ruby.
размещение поведения, которое разделяется между контроллерами в модуле, на мой взгляд, является хорошей практикой. С другой стороны, помещение его в помощника потенциально вводит в заблуждение, и я бы избегал этого. Поместите его в" стандартный " модуль.
это философские вопрос на том же уровне, что и аргумент, который ставит под сомнение метод REST, предоставленный в строительных лесах, и если леса вообще стоит иметь. Вы должны учитывать тот факт, что учебник книга в RailsTutorial.org является get-up-and-go Rails инструктивным руководством. Поэтому для той цели, которой он служит, я думаю, что он выполняет свою работу.
однако, есть ли лучшее место для размещения кода, необходимого для контроллеров и представлений? Да, есть.
- некоторые могут следовать Майкл Хартл формы Railstutorial и включают в себя весь
SessionHelper
наApplicationController
- другие могут решить выставить только основные помощники, необходимые для просмотра, т. е.
sign_in
,sign_out
,current_user
и тому подобное. - Я вижу предложение поставить такой код
/lib
каталог и включить его там, где это необходимо.
все жизнеспособные варианты. Что бы вы ни взяли, это может не иметь значения в производительности, потому что Ruby должен будет проанализировать файл, из которого вы хотите вызвать (или включить) класс, модуль или метод. Что происходит, прежде чем какой-либо код выполняется в классе, Ruby проходит через весь класс один раз, чтобы узнать, что в нем. Все зависит от того, что нужно и дизайн своего приложения
FWIW, я сохраняю текущего пользователя в классе пользователя:
class User < ActiveRecord::Base
cattr_accessor :current
...
end
на это можно ссылаться во всех 3 уровнях MVC; он установлен в контроллере так (и также при входе в систему, конечно):
def set_current_user
User.current = (session[:user_id]) ? User.find_by_id(session[:user_id]) : nil
end
среди прочего, это позволяет мне иметь журналы аудита на уровне ActiveRecord, которые захватывают текущего пользователя (когда это применимо).