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, которые захватывают текущего пользователя (когда это применимо).