Apparently, you can't access the params hash in a Pundit policy. It makes sense that they want to expose as little information to the policies as possible. But one use case I'm running into, which I would think would be quite common, is to check that the current_user is the user from the params.
So here's my new action in my controller:
class ReviewsController < ApplicationController
...
def new
@user = User.friendly.find(params[:user_id])
unless current_user.admin? || current_user.id == @user.id
flash[:alert] = 'Access denied.'
redirect_to root_url
end
@review = @user.reviews.build
end
...
end
So here, I'm saying to authorize if the user is an admin, or the current user is the same as the one in the URL. Otherwise, the user with the id of 2 could go to /users/1/reviews/new.
There doesn't seem to be any way to handle this in the policy, because I can't pass the params[:user_id] into the policy.
Is there a way to handle this authorization scheme from a Pundit policy, rather than handling auth logic in my controller?
Not sure if this question is out of date.
When pundit does the authorization in the controller, it will pass two objects. One is record and another is current_user. But you only need to provide the record when you call the authorize method, current_user will be passed automatically.
#authorize(record, query = nil) ⇒ true
In your case, when you call authorize(@user, :new?), in your policy, @user will be referenced as record, and current_user will be referenced as user.
Therefore, in your policy:
class UserPolicy < ApplicationPolicy
def new?
user.admin? || record == user
end
end
And you can check the policy in your controller:
class ReviewsController < ApplicationController
...
def new
@user = User.friendly.find(params[:user_id])
authorize(@user, :new?)
@review = @user.reviews.build
end
...
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With