Rails: Access to current_user from within a model in Ruby on Rails
I'd say your instincts to keep current_user
out of the model are correct.
Like Daniel I'm all for skinny controllers and fat models, but there is also a clear division of responsibilities. The purpose of the controller is to manage the incoming request and session. The model should be able to answer the question "Can user x do y to this object?", but it's nonsensical for it to reference the current_user
. What if you are in the console? What if it's a cron job running?
In many cases with the right permissions API in the model, this can be handled with one-line before_filters
that apply to several actions. However if things are getting more complex you may want to implement a separate layer (possibly in lib/
) that encapsulates the more complex authorization logic to prevent your controller from becoming bloated, and prevent your model from becoming too tightly coupled to the web request/response cycle.
ruby on rails - current_user on model
current_user
is a devise helper to be used on Views and Controllers. If you have an instance method that needs the current_user
you should probably move it's logic to a Controller.
It's better explained here: Access to current_user from within a model in Ruby on Rails
how access to helper current_user in model rails?
You can't (or, at the very least, you really really shouldn't).
Your models have no access at all to your currently instantiated controller. Your models are supposed to be designed in such a way that there might not even be a request or a user actually interacting interactively with the system (think ActiveJob).
You need to pass current_user
into your model layer.
Your specific problem is that you've invented something called helpers
. That isn't a thing, it's nil
, so you get your NoMethodError
on nil:nilClass
error. current_user
is an instance method, so you would need to invoke it directly on an instance of your controller, not on the class itself.
Access Devise's current_user in Model
Essentially, this kind of logic doesn't belong in a Model, so you're best to pass current_user
in through a function in the model or on creation. This answer sums it up.
I know, I know, that's not the answer you wanted. Unfortunately, it may be cleaner looking to you, but it adds overhead to your model that you really don't want.
current_user in Model
It's simple. Pass the current_user
as an argument.
def tagged_users(current_user)
# ...
end
And use it in the view.
<% node.tagged_users(current_user)...
Alternatively, you can set an attr_accessor
in the Node
. But I would pass the user in.
class Node
attr_accessor :current_user
end
Then, whenever you instant it's a node:
@node.current_user = current_user
How to access current_user object in model?
current_user
is not available in any model, to access current_user
in model do this
In your application controller
before_filter :set_current_user
def set_current_user
Team.current_user = current_user
end
in your Team
model add this line
cattr_accessor :current_user
Congrats, now current_user
is available in every model, to get the current user just use the following line everywhere
Team.current_user
NOTE: Restart the server after adding the lines mentioned above!
Now in your question you can use it like
def set_default_url
if Team.current_user.id == self.user_id
"/assets/default_black_:style_logo.jpg"
else
"/assets/default_:style_logo.jpg"
end
end
Hope this helps!
How to access to 'current_user' outside of controller and model
If the engine is running in the same thread then perhaps you could store the current_user in the Thread.
class ApplicationController < ActionController::Base
around_action :store_current_user
def store_current_user
Thread.current[:current_user] = current_user
yield
ensure
Thread.current[:current_user] = nil
end
end
Then in your filter_comments.rb
you can define a method
def current_user
Thread.current[:current_user]
end
Related Topics
Ruby Objects and Json Serialization (Without Rails)
How to Check Whether a String Contains a Substring in Ruby
In Ruby How to Overload the Initialize Constructor
Rails Update_Attributes Without Save
Double Colons Before Class Names in Ruby
Ruby 'Require' Error: Cannot Load Such File
How to 'Validate' on Destroy in Rails
How to Override a Setter Method in Ruby on Rails
Library Not Loaded: /Opt/Local/Lib/Libssl.1.0.0.Dylib (Loaderror)
Limitations in Running Ruby/Rails on Windows
"Bin/Rails: No Such File or Directory" W/ Ruby 2 & Rails 4 on Heroku
Find_Spec_For_Exe': Can't Find Gem Bundler (≫= 0.A) (Gem::Gemnotfoundexception)
Cannot Install Json Gem in Rails Using Windows