Post: hidden: boolean
I want the logged in user could see all the posts, and the non-logged-in user only have access to posts whose hidden fields are false. So I write like this in cancan's Ability Model:
if user_signed_in?
can :read, Post
else
can :read, Post, :hidden => false
end
but accessing the helper user_signed_in is not allowed in Model. As stated in this question: Rails 3 devise, current_user is not accessible in a Model ?. While we could using some tricks to access the helper, its not proper to do that
So, how could I authorize the not-logged-in user properly? Or just use "Include" to use this helper ??
Or should I put this in authentication part? but how?
All you need to do is this:
With devise, the
current_user
helper method returns the current user when logged in but returns nil when not logged in. It is available in the controllers and views. By default, CanCan does all authorization checks against the return of thecurrent_user
method.Now whenever the
can?
method is called from a view or a controller, the return ofcurrent_user
will be passed to a new instance ofAbility
as the local variableuser
.To check if the user was logged in, I choose to use
User.exists?()
. It's a class method forActiveRecord::Base
that will check if thatuser
object is persisted in the database. Any other way will work just as well though. For instance, this would work just as well or better:This will check if the default devise password field exists for the
user
instance. If you haven't done anything too crazy, this will only return a value if the user is logged in. If the second option works for your situation, it may be superior because you won't even have to query the database.Semi-relevant tip, check out a role handling gem like Rolify. It is great when used in conjunction with CanCan.