2012-02-26 3 views
0

Ищете лучший способ проверки прав собственности в модели Rails без раздувания моих контроллеров. Это означает, что мне нужно каким-то образом передать current_user модели.Понимание жизненного цикла атрибута класса модели Rails

Я в настоящее время установки атрибута класса на модели пользователя в CURRENT_USER в начале каждого запроса:

class User < ActiveRecord::Base 
    cattr_accessor :current_user 
end 

class ApplicationController < ActionController::Base 
    before_filter :set_current_user 
    def set_current_user 
    User.current_user = current_user 
    end 
end 

Я не уверен, если я полностью понимаю всю жизнь User.current_user в этом сценарий. Возможно ли, что значение может измениться во время запроса?

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

+0

Зависит от того, запускаете ли вы приложение в многопоточном режиме или нет. –

ответ

2

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

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

+0

, за исключением того, что, когда пользователь, не прошедший проверку подлинности, посещает, он будет установлен в nil – tybro0103

+0

У меня совсем другая проблема, которая, по-видимому, вызвана Эта проблема. Можете ли вы предоставить какие-либо ссылки, которые обсуждают, как переменные хранятся в памяти между запросами на Heroku? –

1

Это, безусловно, правильный подход, если вы хотите соответствовать лучшим практикам. current_user - это метод контроллера, и, следуя шаблону Chain-of-responsibility, модель User не должна знать, кем является текущий пользователь.

+1

Это интересно, вы говорите об этом, потому что OP * * указывает модели пользователя, чтобы сохранить, кто является текущим пользователем. –

+0

спасибо ... Я больше беспокоюсь о жизни, хотя ... возможно ли, что значение может измениться во время запроса? – tybro0103

+0

Это просто неправильно. Вы скрываете состояние в месте, которого не должно быть. Что делать, если кто-то меняет 'current_user' во время запроса. Тогда два вара будут не синхронизированы. – theodorton

0

Это небезопасный подход. Держите свое состояние в контроллерах и бизнес-логике в моделях.

Если текущий_узел должен быть передан на уровень модели, то модели не должно заботиться о том, кто это. Вы всегда можете использовать ассоциации для фильтрации доступа к контенту.

current_user.widgets.find(params[:id])

+0

Я считаю, что вы ошибаетесь. Это не для фактического хранения какого-либо состояния; это фактически для бизнес-логики. Это позволяет мне проверять право собственности на модель при обновлении. Например, при проверке модели Post: self.user_id == User.current_user – tybro0103

+0

Это должно войти в контроллер. Они ограничивают доступ, а не сами модели. Вы можете сделать это, переработав метод обновления на вашем контроллере, чтобы использовать find в ассоциации has_many. – theodorton

+0

Я знаю, что это религиозная вещь, будь то бизнес-логика или нет, но я считаю, что это так. Я мог бы создать метод в Post, например: def is_owner? (Пользователь) и использовать этот метод в контроллере, но это утомительно делать в каждом действии. – tybro0103

Смежные вопросы