What do I need to do to be able to use an acts_as_authenticated
current_user in a model?
Is there some sort of include or require I can do some where that would
allow this?
Here is what I am trying to do:
class Setting < ActiveRecord::Base
before_create :created_by_user # create only
before_save :updated_by_user # both, create and update
def created_by_user
self.created_by_user_id = current_user.id
self.created_by_user_login = current_user.login
end
def updated_by_user
self.updated_by_user_id = current_user.id
self.updated_by_user_login = current_user.login
end
end
But it gives me this error:
undefined local variable or method `current_user’ for
#Setting:0x35188f8
Anyone know how to accomplish what I am trying to do? I still can not
figure it out. I know I can just update these fields from the actions in
my controllers (that is how I have it working for now), but it breaks
DRY and it is more elegant in the model.
scott wrote:
What do I need to do to be able to use an acts_as_authenticated
current_user in a model?
Is there some sort of include or require I can do some where that would
allow this?
Here is what I am trying to do:
class Setting < ActiveRecord::Base
before_create :created_by_user # create only
before_save :updated_by_user # both, create and update
def created_by_user
self.created_by_user_id = current_user.id
self.created_by_user_login = current_user.login
end
def updated_by_user
self.updated_by_user_id = current_user.id
self.updated_by_user_login = current_user.login
end
end
But it gives me this error:
undefined local variable or method `current_user’ for
#Setting:0x35188f8
undefined local variable or method `current_user’ for
#Setting:0x35188f8
You can’t do this because models have no concept of the session. How
could they? These are the same models that could be executed in DB
migrations or console scripts, for example. One solution, is to use a
class method in your model. Richard L. has a solution for this: http://livsey.org/2005/07/16/adding_created_by_and_updated_by_to_rails/
class User < ActiveRecord::Base
cattr_accessor :current_user
…
end
class ApplicationController < ActionController::Base
include AuthenticatedSystem
before_filter { |c| User.current_user = c.current_user }
end
Now, you can access the current user from your models with
User.current_user. In console scripts, simply set the current user
before performing any operations:
Thanks Rick,
That article you linked to looks helpful, I think after I read it more
carefully, I will learn a lot more about how rails works.
I will give what you said a try tomorow. I am still learning how to work
with MVC in rails. I have a good grasp on VC, I am working on what
can/can’t be done in models to make my apps cleaner.
-Scott
undefined local variable or method `current_user’ for
#Setting:0x35188f8
You can’t do this because models have no concept of the session. How
could they? These are the same models that could be executed in DB
migrations or console scripts, for example. One solution, is to use a
class method in your model. Richard L. has a solution for this: http://livsey.org/2005/07/16/adding_created_by_and_updated_by_to_rails/
class User < ActiveRecord::Base
cattr_accessor :current_user
…
end
class ApplicationController < ActionController::Base
include AuthenticatedSystem
before_filter { |c| User.current_user = c.current_user }
end
Now, you can access the current user from your models with
User.current_user. In console scripts, simply set the current user
before performing any operations:
Your advice worked except I was getting an error saying method
current_user is protected. I had to edit the authenticated_system.rb.
public
def current_user @current_user ||= session[:user] ? User.find_by_id(session[:user]) : nil
end
protected
Is having this method public a security problem?
Rick O. wrote:
You can’t do this because models have no concept of the session. How
could they? These are the same models that could be executed in DB
migrations or console scripts, for example. One solution, is to use a
class method in your model. Richard L. has a solution for this: http://livsey.org/2005/07/16/adding_created_by_and_updated_by_to_rails/
class User < ActiveRecord::Base
cattr_accessor :current_user
…
end
class ApplicationController < ActionController::Base
include AuthenticatedSystem
before_filter { |c| User.current_user = c.current_user }
end
Now, you can access the current user from your models with
User.current_user. In console scripts, simply set the current user
before performing any operations:
Something like this problem might also occur in other cases.
So, for example, you might get "undefined local variable or method
`current_user’ " if you’ve not granted all to your project user during
development.
This may occur inadvertently as you drop test and development database
that have been corrupted and re-“create” them (as in MySQL) but forget
the “grant all” step.
In this case, you see the errors when you try to access the application
through the browser.
Once you do “grant all,” you still see the problem in the browser.
What you need to do after “grant all” is to re-start WEBRick because the
previous DB connection remains with a user with no privileges remains
active until you stop the WEBRick rails container … so to speak.
masood mortazavi
scott wrote:
What do I need to do to be able to use an acts_as_authenticated
current_user in a model?
Is there some sort of include or require I can do some where that would
allow this?
Here is what I am trying to do:
class Setting < ActiveRecord::Base
before_create :created_by_user # create only
before_save :updated_by_user # both, create and update
def created_by_user
self.created_by_user_id = current_user.id
self.created_by_user_login = current_user.login
end
def updated_by_user
self.updated_by_user_id = current_user.id
self.updated_by_user_login = current_user.login
end
end
But it gives me this error:
undefined local variable or method `current_user’ for
#Setting:0x35188f8
Am I reading correctly that this is just creating a class method on
User that grabs the current_user out of the session in the
ApplicationController before_filter?
Er, leaving aside the fact that this plugin seemed to return the
incorrect user when I tried it.
I freely admit that the current Userstamp plugin has some
shortcomings (which is why I’m working on the second iteration–to
be release soon), but since the plugin simply accesses the
currently logged in user via whatever is in the session, are you
sure it was the plugin that returned the incorrect user?
Could be. I’m currently using acts_as_authenticated, but with enough
customizations that anything that normally works with
acts_as_authenticated will likely break anyway.
Am I reading correctly that this is just creating a class method on
User that grabs the current_user out of the session in the
ApplicationController before_filter?
You are mostly correct in your interpretation of what the plugin does,
except you forgot to mention the automatic saving of the current user
to the created_by and updated_by attributes of your ActiveRecord
objects.
Er, leaving aside the fact that this plugin seemed to return the
incorrect user when I tried it.
I freely admit that the current Userstamp plugin has some shortcomings
(which is why I’m working on the second iteration–to be release
soon), but since the plugin simply accesses the currently logged in
user via whatever is in the session, are you sure it was the plugin
that returned the incorrect user?
I am using a variant of acts_as_authenticated, which stores the current
user in a thread variable, which overcomes the problems that using
class variable has with concurrency. It has been working fine for me.
Could be. I’m currently using acts_as_authenticated, but with enough
customizations that anything that normally works with
acts_as_authenticated will likely break anyway.
If you are using acts_as_authenticated, you should be able to use the
current_user method that’s included with the AuthenticatedSystem
module in the before filter.
Your advice worked except I was getting an error saying method
current_user is protected. I had to edit the authenticated_system.rb.
public
def current_user @current_user ||= session[:user] ? User.find_by_id(session[:user]) : nil
end
protected
Is having this method public a security problem?
Scott,
I too was having this problem, but it bothered me that there was an
error accessing a protected method inside a class that allowed access to
other protected methods. It looks like the scope of the before_filter
block is not inside the Controller. To solve this problem without
opening the current_user scope, do the following:
class ApplicationController < ActionController::Base
include AuthenticatedSystem
before_filter :login_from_cookie # <-- if you use this
before_filter :set_current_user
rest of your ApplicationController body
protected
def set_current_user
User.current_user = self.current_user
end
Anyone know why the scope is off for the block, and if this is by design
or a defect?
-Dennis
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.