Any examples of using can?

I'm trying to see if a user (actor) can perform an update action on target user.
iex(9)> MyApp.Users.can?({target_user, :update}, actor)
** (ArgumentError) Invalid action/query/changeset "nil"
(ash 2.9.19) lib/ash/api/api.ex:610: Ash.Api.can/4
(ash 2.9.19) lib/ash/api/api.ex:522: Ash.Api.can?/4
iex:9: (file)
iex(9)> MyApp.Users.can?({target_user, :update}, actor)
** (ArgumentError) Invalid action/query/changeset "nil"
(ash 2.9.19) lib/ash/api/api.ex:610: Ash.Api.can/4
(ash 2.9.19) lib/ash/api/api.ex:522: Ash.Api.can?/4
iex:9: (file)
8 Replies
ZachDaniel
ZachDaniel•2y ago
this may be a bug something looks strange there...mind updating? I added some code there recently, not to explicitly fix this bug, but maybe it did 😆
Vonagam
Vonagam•2y ago
The problem here is {target_user, :update} I would assume that target_user is of type Ash.Resource.record(), but this is not supported. That form is for {User, :update} (so module of the resource, not the instance of it). To do what you want you can do something like this (can use pipes to shorten it):
changeset = Ash.Changeset.for_update(target_user, :update)
MyApp.Users.can?(changeset, actor)
changeset = Ash.Changeset.for_update(target_user, :update)
MyApp.Users.can?(changeset, actor)
ZachDaniel
ZachDaniel•2y ago
We should probably support that form
Vonagam
Vonagam•2y ago
Looking at the code there is opts[:data] which is used as an initial record by update and destroy. So shorter version will be something like that:
MyApp.Users.can?({MyApp.Users.User, :update}, actor, data: target_user)
MyApp.Users.can?({MyApp.Users.User, :update}, actor, data: target_user)
Other actions do not need initial data, so that's why (I assume) it is only an option and not a supported form.
ZachDaniel
ZachDaniel•2y ago
Yeah, that’s right
Robert Graff
Robert GraffOP•2y ago
Awesome. Thank you everyone!
Blibs
Blibs•2y ago
On the same topic, @Zach Daniel is it right to assume that the can function checks only if the user passes the action policies? Or does it check something else?
ZachDaniel
ZachDaniel•2y ago
Correct, it checks the authorization policies

Did you find this page helpful?