Using Canary / Canada.Can with many_to_many models?

I’m trying to use Canary for authorization, but can’t find any examples of using it with a many_to_many association because the model doesn’t have the belongs_to id in it. Does anyone know how to set up the Canada.Can portion of the configuration when you’re using join_through? I made the join_through table initially without any primary keys. Do I have to change that so I can turn it into a model?

1 Like

The Canada protocol is designed to only operate on data that has been loaded already. This means, in order for it to work with many_to_many associations you’d have to preload them on at least one of your structs.

Since that will require more database queries, I think Canada.can? might not be suitable for this use-case. You’d rather want to query the join table directly.

An alternative would be, of course, a stateful process (such as a GenServer) that keeps your ACL and that would be queried by Canada.can?.

Ok, thank you. I’m looking at another library called PolicyWonk. I’ll see if that works instead.

Well, you’ll still be facing the same problem: You have to decide where to load the join table from your database. Of course you could do that inside the Canada.can? protocol function just like you can do it from within the PolicyWonk policy. I was trying to suggest that this might not be the best way to do it since that will put your database calls into a semi-hidden controller layer.
But if you’re fine with that, you can totally do it with Canada as well :slight_smile:

Awesome, thanks for the feedback. I’m a bit of a neophyte when it comes to backend programming (if that wasn’t apparent already), do you have any tips on what kind of solution you’d cook up for this? My thought is that if I try to roll my own, which is fine because I just need something simple, I would just need a plug that accepts the join table as an argument in the controller and checks it against the current user id.

1 Like