복붙노트

[RUBY-ON-RAILS] 3 유증 레일, CURRENT_USER는 모델에 액세스 할 수 없습니다?

RUBY-ON-RAILS

3 유증 레일, CURRENT_USER는 모델에 액세스 할 수 없습니다?

내 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에 액세스 할 수있는 컨트롤러 ... 이유 모델이 액세스 할 수 없습니다 액세스를 얻을 수있는 방법이 있나요? 또한, 이는 상기와 같은 범위를 생성하기 적당한 장소, 또는 그 제어부에 속하는가?

해결법

  1. ==============================

    1.이미 지적했듯이이 훨씬 이해가되지 않습니다. CURRENT_USER는이 컨트롤러 수준에서 처리되어야 전혀 모델 논리에 속하지 않습니다.

    이미 지적했듯이이 훨씬 이해가되지 않습니다. CURRENT_USER는이 컨트롤러 수준에서 처리되어야 전혀 모델 논리에 속하지 않습니다.

    하지만 당신은 여전히 ​​컨트롤러에서에 매개 변수를 전달, 같은 범위를 만들 수 있습니다 :

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

    이제 컨트롤러를 호출 할 수 있습니다 :

    Model.instanceprojects(current_user)
    
  2. ==============================

    2.이미 허용 대답이를 달성하기 위해 정말 올바른 방법을 제공합니다.

    이미 허용 대답이를 달성하기 위해 정말 올바른 방법을 제공합니다.

    그러나 여기 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
    

    예상대로 우리가 기본적으로 여기에 글로벌 변수를 정의하기 때문에이 작품은, 그러나 그것은 고려 더러운 될 수 있습니다.

  3. ==============================

    3.라이언 베이츠는이 railscast에서 전략의이 종류를 구현하는 매우 안전한 방법으로 배치합니다

    라이언 베이츠는이 railscast에서 전략의이 종류를 구현하는 매우 안전한 방법으로 배치합니다

    이 유료 에피소드 (아래! 나에게 투표하지 않는다)하지만 당신은 무료로 소스 코드를 탐색 할 수 있습니다

    여기에 그는 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) }
    
  4. ==============================

    4.당신은 범위를 사용할 필요가 없습니다. 당신은 트릭을 할해야 컨트롤러에 배치 코드 조각 다음 모델에서 적절한 연결을 설정 한 경우 :

    당신은 범위를 사용할 필요가 없습니다. 당신은 트릭을 할해야 컨트롤러에 배치 코드 조각 다음 모델에서 적절한 연결을 설정 한 경우 :

    @projects = current_user.instance.projects
    
  5. from https://stackoverflow.com/questions/3742785/rails-3-devise-current-user-is-not-accessible-in-a-model by cc-by-sa and MIT license