0

I needed to access the current_user in my another model. I googled and found a few solutions and tried this.

But just one difference: I didn't set the User.current_user in the controller. WHY?

Like in the answer I followed I'm not adding data to my second model from views but by rendering data via a url (with open-uri, it's csv data I'm fetching).
So in my second model I do:

Person.create(username: User.current_user.username)  

It gives:

NoMethodError: undefined method `username' for nil:NilClass

which isn't working (which is obvious I guess). In console when I do User.current_user it shows:

1.9.3p448 :002 > User.current_user
=> nil

I think why it isn't working is because I'm accessing the User.current_user directly from model and model cannot get the current_user unless it is given that. (right?)

But this would definitely work if I access it via a login page and set the User.current_user in the controller.

But as I'm directly fetching the data from url, I'm directly making new entries for my Person model in model itself.

So how do I set the User.current_user?

Is there any workaround for this? Edit's for the question's title are required.

Community
  • 1
  • 1
mrudult
  • 2,480
  • 3
  • 35
  • 54

1 Answers1

1

current_user is available by default as a helper method within Devise. From the documentation:

# For the current signed-in user, this helper is available:
current_user

The current_user isn't accessed directly via the model, per se, but rather, though the Devise module, which looks up the User object that is logged into the current session, and then returns to current_user.

Thus, the current user isn't accessed via User.current_user (there is no current_user method on User, as the error message is saying). You access it purely by invoking the current_user helper method within a controller or view.

UPDATE:

You're well advised to keep your controller and model layers separate. One way of doing what you've proposed is to create a class function on the Person model wherein you explicitly pass the username of your User object from within your controller:

# in your controller
Person.create_with_username(:username => current_user.username)

# app/models/person.rb
def self.create_with_username(username)
    self.create(username)
end
zeantsoi
  • 25,857
  • 7
  • 69
  • 61
  • I know that current_user is not a method which can be called on User class.But if you see the link I followed it assings the `current_user` to `User.current_user`. Also I want to access this current_user in my model. – mrudult Sep 02 '13 at 08:58
  • Did you read all the comments indicating that the cited solution __is not thread safe__? You understand that this invariable __will__ cause you problems, correct? The model should be stateless and agnostic to your application state, so the following solution is a far better avenue, IMO: http://stackoverflow.com/a/12713768/1086529 – zeantsoi Sep 02 '13 at 16:43
  • Have you had any luck with the update to my question? Did you find a solution to this? – zeantsoi Sep 02 '13 at 20:16
  • 1
    May I recommend that you do try it and report back with you findings. If it doesn't work, we can move on to finding another solution. – zeantsoi Sep 02 '13 at 20:28
  • okay but will that `create_with_username` method be called automatically within the model every time I make a new **Person?** – mrudult Sep 02 '13 at 20:29
  • If you invoke `Person.create_with_username(:username => current_user.username)`, then yes, it will. – zeantsoi Sep 02 '13 at 20:35
  • Nope. That's not working. May be I'm wrong but I don't think that's gonna work (or the only answer to this question is 'NO' ) because `current_user` is stored in the sesssion I guess. So only when a user is logged in via a browser of so then only we have a value in `current_user`.Only working on model level and invoking a controller action is not possible. – mrudult Sep 02 '13 at 20:49
  • I've tested this and it _does_ work. What is not working about it? – zeantsoi Sep 02 '13 at 20:54
  • @zeanstoi the `current_user.username` value is `nil`. How will it work? From where will you invoke the `Person.create_with_username(:username => current_user.username)`? – mrudult Sep 02 '13 at 20:56
  • Do you mean to suggest that you need to access `current_user` without being logged in? You do understand that that is __not__ how Devise works, correct? It's not even how the answer you've linked to works. Who is the `current_user` if not the ___current user___, after all? – zeantsoi Sep 02 '13 at 20:59
  • @zeanstoi Yeah. The CSV I'm fetching,have data of many **Persons** which belongs to a **Company**. here the company is the `current_user`. So in my model I fetch the csv and make `persons`. But as I have a `has_many` association from company to person I want to assign the company's username to each person of that company.So obiviously when I'm creating `persons`(indirectly via open-uri/csv) the company isn't logged in. That's why I asked for a workaround for this issue. – mrudult Sep 02 '13 at 21:07