Enrique Moreno Tent
Enrique Moreno Tent

Reputation: 25267

Using devise within the models

Is there a way to use devise functions within a model? Let's say, a scope?

For reference, this is what I was thinking of:

scope :available, -> {
    if user_signed_in?
        requestable
    else
        requestable.where.not(books: {owner_id: current_user.id})
    end
}

I would need to use user_signed_in? and current_user in this scope. But I can't. Is there a way to do it?

Upvotes: 2

Views: 270

Answers (2)

Axel Tetzlaff
Axel Tetzlaff

Reputation: 1364

Methods like these are not meant to be used in models. Models are supposed to work outside the controller as well (i.e. directly from the Rails console).

For a more detailed reasoning see:

Access to current_user from within a model in Ruby on Rails

Further there is no global 'store' knowing which users are currently signed in - this is determined within a request, by veryfying the user sends valid session information with his request.

Upvotes: 1

Benjamin Bouchet
Benjamin Bouchet

Reputation: 13181

current_user (and same goes for devise helpers such as user_signed_in?) is only available in your controllers. I've been around that question and ended up by passing current_user to my scopes and model's methods.

In the model:

scope :available, -> (current_user, signed_in) {
    if signed_in
        requestable
    else
        requestable.where.not(books: {owner_id: current_user.id})
    end
}

In the controller:

MyModel.available(current_user, user_signed_in?)

An alternative would be to use request_store (rack based global data storage) to store the current_user of the current request

Upvotes: 2

Related Questions