Acts_as_authenticated current_user in a model?


#1

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


#2

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


#3

I think you would need to include AuthenticatedSystem somehow


#4

What errors does it cause if you put it directly in your setting.rb?


#5

Paul B. wrote:

What errors does it cause if you put it directly in your setting.rb?

When I put it inside the class, I get:
undefined method `helper_method’ for Setting:Class

When I put it before the class, I get:
undefined method `helper_method’ for Object:Class


#6

Paul B. wrote:

I think you would need to include AuthenticatedSystem somehow

Thanks for the reply.

I have tried putting “include AuthenticatedSystem” in various places in:
setting.rb (model)
environment.rb
application.rb
application_helper.rb

Doing any of the above causes other errors. Any other possibilities I am
overlooking, or is leaving it in my controllers my only option?


#7

On 1/15/06, scott removed_email_address@domain.invalid wrote:

before_create :created_by_user # create only
end

end


But it gives me this error:


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:

User.current_user = User.find(1)
@setting.save


rick
http://techno-weenie.net


#8

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. :slight_smile:
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

Rick O. wrote:

On 1/15/06, scott removed_email_address@domain.invalid wrote:

before_create :created_by_user # create only
end

end


But it gives me this error:


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:

User.current_user = User.find(1)
@setting.save


rick
http://techno-weenie.net


#9

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:

User.current_user = User.find(1)
@setting.save


rick
http://techno-weenie.net


#10

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


#11

On Jan 23, 2007, at 9:12 PM, Carl J. wrote:

http://delynnberry.com/projects/userstamp/

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.

-faisal


#12

you could also just use this:

http://delynnberry.com/projects/userstamp/


#13

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.

-faisal


#14

On Jan 23, 2007, at 9:12 PM, Carl J. wrote:

http://delynnberry.com/projects/userstamp/

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?


DeLynn B.
removed_email_address@domain.invalid


#15

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.

Gregg


#16

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.


DeLynn B.
removed_email_address@domain.invalid


#17

scott wrote:

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