Rails 3 разработать, current_user не доступен в модели? - PullRequest
46 голосов
/ 18 сентября 2010

в моей модели project.rb я пытаюсь создать область с динамической переменной:

scope :instanceprojects, lambda { 
    where("projects.instance_id = ?", current_user.instance_id)
} 

Я получаю следующую ошибку:

undefined local variable or method `current_user' for #<Class:0x102fe3af0>

Где в контроллере я могу получить доступ current_user.instance_id ... Есть ли причина, по которой модель не может получить к ней доступ, и способ получить доступ? Кроме того, это правильное место для создания области, как указано выше, или она принадлежит контроллеру?

Ответы [ 4 ]

73 голосов
/ 18 сентября 2010

Это не имеет особого смысла, как вы уже указали.Current_user вообще не принадлежит логике модели, он должен обрабатываться на уровне контроллера.

Но вы все равно можете создать такую ​​область видимости, просто передав ей параметр из контроллера:

scope :instanceprojects, lambda { |user|
    where("projects.instance_id = ?", user.instance_id)
} 

Теперь вы можете вызвать его в контроллере:

Model.instanceprojects(current_user)
31 голосов
/ 26 июля 2012

Уже принятый ответ обеспечивает действительно правильный способ достижения этого.

Но вот поточно-ориентированная версия User.current_user трюка.

class User
  class << self
    def current_user=(user)
      Thread.current[:current_user] = user
    end

    def current_user
      Thread.current[:current_user]
    end
  end
end

class ApplicationController
  before_filter :set_current_user

  def set_current_user
    User.current_user = current_user
  end
end

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

8 голосов
/ 08 ноября 2012

Райан Бейтс излагает довольно безопасный способ реализации такой стратегии в этом сообщении

Это платный эпизод (не голосуйте против меня!), Но вы можете бесплатно просмотреть исходный код

Здесь он создает current_tenant метод, но вместо него можно легко заменить current_user.

Вот ключевые биты кода ...

#application_controller.rb
around_filter :scope_current_tenant

private

def current_tenant
  Tenant.find_by_subdomain! request.subdomain
end
helper_method :current_tenant

def scope_current_tenant
  Tenant.current_id = current_tenant.id
  yield
ensure
  Tenant.current_id = nil
end

#models/tenant.rb

def self.current_id=(id)
  Thread.current[:tenant_id] = id
end

def self.current_id
  Thread.current[:tenant_id]
end

Тогда в модели вы можете сделать что-то вроде ...

default_scope { where(tenant_id: Tenant.current_id) }
0 голосов
/ 18 января 2015

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

@projects = current_user.instance.projects
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...