Доступ к current_user из модели в Ruby on Rails

Стиль кодирования довольно важен. Большинство крупнейших строительных компаний имеет документ, который определяет необходимые соглашения о присвоении имен, комментируя инструкции и другие небольшие вещи сделать с инструкциями по архитектуре и стилем кода.

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

Просто удостоверяются, что это не переходит к уровню менеджера, вынуждающего разработчика вносить изменение в обзоре кода от чего-то вроде этого:

if( someBool() ) doSomething();
else doNothing();

К чему-то вроде этого просто, потому что они "чувствуют", что это - "лучший" стиль:

if( someBool() )
{
    doSomething();
}
else
{
    doNothing();
}

Просто имейте причины лучше, чем персональное предпочтение требований стиля, и мы можем все быть более счастливыми.

69
задан Arslan Ali 21 November 2016 в 12:22
поделиться

5 ответов

Я бы сказал, что ваши инстинкты держать current_user вне модели верны

Как и Дэниел, я сторонник худых контроллеров и толстых моделей, но есть еще и четкое разделение обязанностей. Назначение контроллера - управлять входящим запросом и сеансом. Модель должна быть способна ответить на вопрос «Может ли пользователь x сделать y с этим объектом?», Но для нее бессмысленно ссылаться на current_user . Что делать, если вы находитесь в консоли? Что, если это задание cron?

Во многих случаях с правильным API разрешений в модели это можно решить с помощью однострочных before_filters , которые применяются к нескольким действиям.

44
ответ дан 24 November 2019 в 13:44
поделиться

Что ж, я предполагаю, что current_user , наконец, является экземпляром пользователя, так почему бы не Чтобы добавить эти разрешения в модель Пользователь или в модель данных, если вы хотите, чтобы разрешения применялись или запрашивались?

Я предполагаю, что вам нужно как-то реструктурировать свою модель и передать текущему пользователю в качестве параметра, например:

class Node < ActiveRecord
  belongs_to :user

  def authorized?(user)
    user && ( user.admin? or self.user_id == user.id )
  end
end

# inside controllers or helpers
node.authorized? current_user
8
ответ дан 24 November 2019 в 13:44
поделиться

Я использую плагин декларативной авторизации, и он делает что-то похожее на то, что вы упомянули, с current_user Он использует before_filter чтобы вытащить current_user и сохранить его там, где слой модели может получить к нему доступ. Выглядит это так:

# set_current_user sets the global current user for this request.  This
# is used by model security that does not have access to the
# controller#current_user method.  It is called as a before_filter.
def set_current_user
  Authorization.current_user = current_user
end

Однако я не использую модельные возможности декларативной авторизации. Я сторонник подхода «Тощий контроллер - толстая модель», но мне кажется, что авторизация (как и аутентификация) - это то, что принадлежит уровню контроллера.

и он делает что-то похожее на то, что вы упомянули с current_user . Он использует before_filter для извлечения current_user и сохранения его там, где слой модели может добраться до него. Выглядит это так:

# set_current_user sets the global current user for this request.  This
# is used by model security that does not have access to the
# controller#current_user method.  It is called as a before_filter.
def set_current_user
  Authorization.current_user = current_user
end

Однако я не использую модельные возможности декларативной авторизации. Я сторонник подхода «Тощий контроллер - толстая модель», но мне кажется, что авторизация (как и аутентификация) - это то, что принадлежит уровню контроллера.

и он делает что-то похожее на то, что вы упомянули с current_user . Он использует before_filter , чтобы вытащить current_user и сохранить его там, где слой модели может добраться до него. Выглядит это так:

# set_current_user sets the global current user for this request.  This
# is used by model security that does not have access to the
# controller#current_user method.  It is called as a before_filter.
def set_current_user
  Authorization.current_user = current_user
end

Однако я не использую модельные возможности декларативной авторизации. Я сторонник подхода «Тощий контроллер - толстая модель», но мне кажется, что авторизация (как и аутентификация) - это то, что принадлежит уровню контроллера.

4
ответ дан 24 November 2019 в 13:44
поделиться

Это есть в моем приложении. Он просто ищет текущий сеанс контроллера [: user] и устанавливает его в переменную класса User.current_user. Этот код работает в продакшене и довольно прост. Хотел бы я сказать, что это я придумал, но я полагаю, что позаимствовал это у интернет-гения в другом месте.

class ApplicationController < ActionController::Base
   before_filter do |c|
     User.current_user = User.find(c.session[:user]) unless c.session[:user].nil?  
   end
end

class User < ActiveRecord::Base
  attr_accessor :current_user
end
5
ответ дан 24 November 2019 в 13:44
поделиться

Хотя на этот вопрос многие ответили, я просто хотел быстро добавить свои два цента.

Использование подхода #current_user в модели User следует применять с осторожностью из-за безопасности потоков .

Можно использовать класс / одноэлементный метод для User, если вы не забыли использовать Thread.current как способ хранения и получения ваших значений. Но это не так просто, потому что вам также нужно сбросить Thread.current, чтобы следующий запрос не унаследовал разрешения, которых он не должен.

Я пытаюсь сделать следующее: если вы сохраняете состояние в классе или синглтоне переменных, помните, что вы бросаете поток безопасности в окно.

36
ответ дан 24 November 2019 в 13:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: