I'm setting up an admin ability using Cancancan. I have an association where a room
has_one:group, through: :property
I'm aware that one can't pass an object through using cancancan, but we can check abilities by using a hash.
#ability.rb
if user.has_role?(:admin)
can :manage, Room, :group => { :id => user.group_id }
end
The above ability check works when I'm loading my index, show, update, edit and destroy methods, but doesn't work when I'm loading the new or create methods. I know that Cancancan passes any conditions as a hash, like this , but I don't think it's passing my hash because groups are set up as an association instead of a column on each room object.
#rooms_controller.rb
class RoomsController < ApplicationController
load_and_authorize_resource
def new
@room = Room.new
end
end
My question is, how can I check this ability on new and create methods, preferably without adding new columns to my objects.
Any help is appreciated
Thanks
If you are using load_and_authorize_resource
, you shouldn't be doing @room = Room.new
in the new
method. The load_and_authorize_resource
method does that for you. So my assumption is you're overwriting the one it's initializing.
The same would apply to all of the other methods in RoomsController
, unless you want to override how the image is loaded (eager loading, etc.) or searched for.
Try doing the following.
To check against a rule with custom attributes the new object you create must have those attributes. ie a Room with the current user's group_id
#rooms_controller.rb
class RoomsController < ApplicationController
def new
@room = Room.new(group_id: current_user.group_id)
authorize! @room
end
end
Alternatively I think you can specify custom params for an action via https://github.com/CanCanCommunity/cancancan/blob/develop/docs/changing_defaults.md#strong-parameters
So that might (I haven't tested) look like:
#rooms_controller.rb
class RoomsController < ApplicationController
load_and_authorize_resource
def new
puts @room
end
def room_params
@room_params = params.require(:room).permit(:group_id)
@room_params[:room].merge(group_id: current_user.group_id) # ??
@room_params
end
end
That said, you might not even want to restrict the new action, since the resource doesn't create anything, it might not matter who gets here.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.