Rails 3 devise, current_user not available in model?

in my project.rb model, I am trying to create a scope with a dynamic variable:

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

I get the following error:

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

Where in the controller can I access current_user.instance_id ... Is there a reason why the model cannot access it and how to access it? Also, is this a suitable place to create the area as described above, or does it belong to the controller?

+45
ruby-on-rails activerecord ruby-on-rails-3
Sep 18 '10 at 17:47
source share
4 answers

This does not make much sense, as you have already indicated. Current_user does not apply to model logic at all; it should be processed at the controller level.

But you can still create such an area, just pass it a parameter from the controller:

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

Now you can call it in the controller:

 Model.instanceprojects(current_user) 
+71
Sep 18 2018-10-18
source share

An already accepted answer provides a truly correct way to achieve this.

But here is the thread-safe version of the trick 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 

This works as expected, but it can be considered dirty because we basically define a global variable here.

+26
Jul 26 '12 at 13:23
source share

Ryan Bates offers a fairly safe way to implement such a strategy in this railscast

This is a paid episode (don’t vote!), But you can view the source code for free

Here he creates the current_tenant method, but you can easily replace current_user instead.

Here are the key bits of code ...

 #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 

Then in the model you can do something like ...

 default_scope { where(tenant_id: Tenant.current_id) } 
+8
Nov 08
source share

You do not need to use areas. If you have set up the appropriate associations in the models, the next piece of code placed in the controller should do the trick:

 @projects = current_user.instance.projects 
0
Jan 18 '15 at 19:32
source share



All Articles