Forum: Ruby on Rails acts_as_authenticated current_user in a model?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
scott (Guest)
on 2006-01-16 04:16
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>
scott (Guest)
on 2006-01-17 02:30
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>
Paul B. (Guest)
on 2006-01-17 02:46
(Received via mailing list)
I think you would need to include AuthenticatedSystem somehow
scott (Guest)
on 2006-01-17 04:12
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?
Paul B. (Guest)
on 2006-01-17 04:52
(Received via mailing list)
What errors does it cause if you put it directly in your setting.rb?
scott (Guest)
on 2006-01-17 05:31
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
Rick O. (Guest)
on 2006-01-17 05:43
(Received via mailing list)
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...

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
scott (Guest)
on 2006-01-17 06:21
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

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...
>
> 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
scott (Guest)
on 2006-01-17 22:30
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...
>
> 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
M. Mortazavi (Guest)
on 2007-01-24 04:03
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>
Carl J. (Guest)
on 2007-01-24 04:12
you could also just use this:

http://delynnberry.com/projects/userstamp/
Faisal N Jawdat (Guest)
on 2007-01-24 07:27
(Received via mailing list)
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
DeLynn B. (Guest)
on 2007-01-24 08:22
(Received via mailing list)
> 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
http://delynnberry.com
Faisal N Jawdat (Guest)
on 2007-01-24 08:49
(Received via mailing list)
> 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
DeLynn B. (Guest)
on 2007-01-24 09:20
(Received via mailing list)
> 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
http://delynnberry.com
Gregg K. (Guest)
on 2007-01-24 18:58
(Received via mailing list)
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
Dennis Bell (Guest)
on 2007-01-24 20:04
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
This topic is locked and can not be replied to.