Skip to main content

Authorization with Pundit Discussion

General • Asked by Chris Oliver
Related episode: Authorization with Pundit

Gravatar
Shahnawaj Alom Limon on

It is really helpful. I've also seen CanCan. But I'm little bit confuse, which one should I use? Do you have any suggestion? Beside this I've a request that it'll be very helpful, if provide a video on angularjs with rails.

Gravatar
Chris Oliver (159,850 XP) on

Use whichever one makes the most sense to you. I tend to prefer Pundit, but that's my preference.

Gravatar
Shahnawaj Alom Limon on

Thanks.

Gravatar
Jay Killeen (1,570 XP) on

Pundit seems to look more like the rest of my app. I do like that in cancancan you can do the can? wrap which looks really sweet and you have the authorize resources in your controllers but once I get into abilities.rb things start to get messy.

Testing with Rspec seems to look quite similar for both after viewing an existing app I have inherited and looked at this article from Thunderbolt Labs http://thunderboltlabs.com/....

This article was also a good read to get the initial purpose for pundit http://www.elabs.se/blog/52....


Gravatar
Guest on

Cancan is not really good for scaling. If your app grows larger later, Pundit will be much better.

Here is a good article explaining why.

http://www.distilnetworks.c...


Gravatar
Ryan Swapp (190 XP) on

Great video! I've been searching for a good intro to authorization and this was perfect. Thanks!


Gravatar
Kohl Kohlbrenner on

I have a couple of questions: When are you actually passing in user and record into the the Pundit class because you never explicitly call ApplicationPolicy.new or PostPolicy.new ? How does Pundit know to assign a post to record variable and a user to user variable? Lastly does pundit know to associate @post with the PostPolicy?

Gravatar
Chris Oliver (159,850 XP) on

You're always calling PostPolicy.new but Pundit provides a helper that creates the new policy and sends in those objects.

Since we inherited from ApplicationPolicy, the initialize method there is the one that sets the user and record variables. We created that, not Pundit so you have full control there.

When you call "authorize @post" it looks at the @post.class which is Post. Then it makes that a string, adds "Policy" on the end and looks up that class which would be "PostPolicy". That's how it knows to grab the right policy.


Gravatar
alexander kehaya (900 XP) on

Hey @excid3:disqus I'm getting a strange error towards the end of the video where we add user == post.user I don't understand why this is happening because I have Devise setup properly. Any suggestions?

Gravatar
Chris Oliver (159,850 XP) on

The error is happening inside Pundit. Check line 11 in your category_policy.rb. You're calling ".user" on something there that isn't valid. :)

Gravatar
alexander kehaya (900 XP) on

Yeah I've been playing with it for awhile. My models look correct, user has_many categories and category belongs_to user but I'm still nt able to call category.user. I went in rails console and the associations are working.

Gravatar
Chris Oliver (159,850 XP) on

Is "category" an instance or the class of the model itself? Only the instances have the relation so maybe you're testing the model? You may want to inspect exactly what the variable "category" is in the console.

Gravatar
alexander kehaya (900 XP) on

category is a class of the model (I think:). I've not had this issue before. Should be pretty straight forward.

When I write category.inspect this is the output. (this is for the first category.)

"#<category id:="" 5,="" name:="" \"discovery="" tools\",="" created_at:="" \"2015-09-01="" 17:41:24\",="" updated_at:="" \"2015-09-01="" 17:41:24\",="" user_id:="" 1="">"

Gravatar
alexander kehaya (900 XP) on

ok I got it... I was calling the class in the view instead of the actual instance... now I get it! learned something new. Thanks @excid3:disqus

Gravatar
Chris Oliver (159,850 XP) on

Whoo! That's one of those gotchas that I didn't even think of until you mentioned it. :) Glad you got it working!


Gravatar
varma on

Great video, I have a question:
How to handle multiple roles with Pundit?

Gravatar
claudiu claudiu (20 XP) on

you can use rolify


Gravatar
Thomas M (460 XP) on

Very useful episode. Two things came into my mind while watching it regarding the best practice using pundit combined with devise:

- Since pundit policy is checking for user presence, devise before_action :authenticate_user! seems redundant. Is it good practice to keep it or delete it ?

- Another thing that seems interesting with pundit is scope, which let you avoid dealing with query starting with current_user.something. I tend to use the User class directly (instead of the current_user) on my queries, it allows me to let the user owning the object (address, avatar) or the admin editing the data simply by navigating on the users#edit page (or registrations#edit if devise). Is it a good practice or there is a better way ? Thank you in advance for your lights.


Gravatar
moeabdol moeabdol (50 XP) on

Hey Chris, thanks for the awesome video; however, I wonder how would you still use Pundit's provided helpers in an Angular raw html view?

For example, as you've explained in the video, you can use:
<% if policy(MyClass).new? %>
Do you know how I can leverage Pundit's helpers in a non erb view?

Thanks


Gravatar
Melanie (1,520 XP) on

Hi Chris, please could you do another podcast that goes deeper than this. I'm struggling big time (current issues outlined here: http://stackoverflow.com/qu... ). It would be great to see you set scopes based on who the current user is and the conditions attaching to the record. I've been trying for 2 years to figure this out now and need some help. Do you think you could show how to use the scope and resolve methods in detail. Thank you


Gravatar
Adrian Valenz on

Yea, I had to use: <% if policy(@post).edit? %> in the Show View. policy(Post).edit? wouldn't work.


Gravatar
Jeremy Christopher Bray on

Hi Chris,

I notice that you add:

class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception

include Pundit

after_action :verify_authorized, unless: :devise_controller?
end

In other tutorials I have seen :

class ApplicationController < ActionController::Base
include Pundit
protect_from_forgery

after_action :verify_policy_scoped, unless: :devise_controller?

end

is there any difference with including things before or after the protect?

Gravatar
Chris Oliver (159,850 XP) on

It shouldn't make any difference. Traditionally people do includes at the very top and that's what I generally do too, but in this case I just pasted below to make it a little more clear.


Gravatar
Josh Zandman on

Hey guys, I'm hoping for some advice on how to set a role for a user when signing up. My signup page has 2 options (as images); music supervisor and artist. Both go to the User/new form. In my User model I added a :role column. My goal is to have a user click an image; either supervisor or artist and when they sign up it adds that role name to the database. I know I could use an option field in the form, but I would love to do it this way.

I added this to my Routes:
devise_scope :user do
get "/users/sign_up/:role", to: 'devise/registrations#new', as: 'new_user_with_role'
end

And each image has it's respected url like:
link_to new_user_with_role_path(role: 'supervisor')

So the url looks like: /users/sign_up/supervisor
I added a hidden field and unsuccessfully tried sucking the params through the field to the database, but I think that's an unsecure way to do this.

Any ideas on a good way to do this? Thanks!


Login or create an account to join the conversation.