SessionsHelper на railstutorial.org: должны ли помощники быть модулями общего назначения для кода, который не нужен в представлениях? - PullRequest
19 голосов
/ 31 марта 2011

railstutorial.org есть предложение, которое кажется мне немного странным.

Предлагает этот код :

class ApplicationController < ActionController::Base 
  protect_from_forgery 
  include SessionsHelper 
end 

include SessionsHelper делает методы доступными из ApplicationController, да, но также делает их доступными в любом представлении. Я понимаю, что аутентификация / авторизация являются сквозными, но действительно ли это лучшее место?

Это кажется мне потенциально слишком широким. Внедрение кода, который реализует, скажем, before_filter, который условно перенаправляет (как делает пример railstutorial.org) в модуль, который чаще всего содержит помощники вида, кажется удивительным.

Будет ли функциональность, которая не является строго необходимой в представлениях, лучше разместить в ApplicationController или в другом месте?

Или я просто слишком много об этом думаю?

Ответы [ 4 ]

20 голосов
/ 20 мая 2011

Действительно, ваше чувство верно.

Я бы реализовал это наоборот: добавьте функции 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
6 голосов
/ 18 мая 2011

Они кажутся пользующимися (подлым) преимуществом того факта, что в Rails хелперы являются просто модулями ruby.на мой взгляд, хорошая практика.С другой стороны, помещение его в хелпер может ввести в заблуждение, и я бы этого избегал.Поместите его в «стандартный» модуль.

4 голосов
/ 24 мая 2011

Это философский вопрос на том же уровне, что и аргумент, который ставит под сомнение метод REST, предоставленный в скаффолдинге, и стоит ли вообще использовать скаффолд.Вы должны учитывать тот факт, что учебное пособие в RailsTutorial.org является инструктивным руководством по Rails.Так что для цели, которую он выполняет, я думаю, что он выполняет свою работу.

Однако, есть ли лучшее место для размещения кода, необходимого между контроллерами и представлениями?Да, есть.

  • Некоторые могут следовать Railstutorial от Michael Hartl и включать все SessionHelper в ApplicationController
  • Другие могут решить выставить только основных помощников, необходимых для представления, т.е. sign_in, sign_out, current_user и т. П.
  • Я вижу предложение поместить такой код в каталог /lib и включить его при необходимости.

Всежизнеспособные варианты.Что бы вы ни выбрали, производительность может не иметь большого значения, потому что Ruby придется анализировать файл, из которого вы хотите вызвать (или включить) класс, модуль или метод.Что происходит, прежде чем какой-либо код выполняется в классе, Ruby один раз просматривает весь класс, чтобы узнать, что в нем.Все зависит от того, что нужно, и дизайна их приложения

2 голосов
/ 25 мая 2011

FWIW, я сохраняю текущего пользователя в классе User:

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

...