Reputation: 120
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
Upvotes: 1
Views: 1316
Reputation: 884
Try doing the following.
To check against a rule with custom attributes the new object you create must have those attributes. i.e. 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.
Upvotes: 0
Reputation: 18193
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.
Upvotes: 1