web-dev-qa-db-ja.com

Rails 3 devise、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...モデルがアクセスできない理由とアクセスする方法はありますか?また、これは上記のようなスコープを作成する適切な場所ですか、それはコントローラーに属しますか?

46
AnApprentice

すでに指摘したように、これはあまり意味がありません。 current_userはモデルロジックにまったく属していません。コントローラーレベルで処理する必要があります。

ただし、コントローラーからパラメーターを渡すだけで、そのようなスコープを作成できます。

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

これで、コントローラーで呼び出すことができます。

Model.instanceprojects(current_user)
73
mdrozdziel

すでに受け入れられている答えは、これを達成するための本当に正しい方法を提供します。

ただし、これはスレッドセーフバージョンの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

これは期待通りに機能しますが、ここでは基本的にグローバル変数を定義しているため、ダーティと見なすことができます。

31
Michał Szajbe

ライアン・ベイツは、この種の戦略を実装するためのかなり安全な方法を示しています この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) }
8
Mark Locklear

スコープを使用する必要はありません。モデルに適切な関連付けを設定している場合、コントローラーに配置された次のコードがトリックを実行するはずです。

@projects = current_user.instance.projects
0
sampi