Eli R.
Eli R.

Reputation: 188

Is it possible to use Can? in ActiveAdmin controllers (using cancancan gem)

Does can? actually work in AA? Using AA 2.6.1 and Rails 6 and Ruby 2.6.5.

I see in the latest AA documentation and many other posts that the can? method should be callable within AA resource controllers e.g.

index do
  column :title, sortable: false
  column :secret_data if can? :manage, Post
end

However if I add such if statements to my :index columns, I will get an error. "undefined method `can?' for nil:NilClass"

This is a simple context which should work for starters, but what I want to do is somewhat more complicated.

I have an AdmixUser model and a Group model, and a nested resource Grouprelationship that stores the role of an AdmixUser in a Group. On the Group#show page there is a table_for a group's relationships as follows:

table_for resource.grouprelationships do
  column :action_test do |gr|
    para link_to "Edit Relationship", edit_admix_grouprelationship_path(gr.id)
 end
end

and in my Ability.rb:

    can :read, Grouprelationship, group_id: mygroups
    can :update, Grouprelationship do |gr|
      user_role=Grouprelationship.find_by(admix_user_id: user.id, group_id: gr.group_id).role
      return true if user_role==Grouprelationship::PI #PI can do anything
    end

The logic here is that if my role in a Group is the 'PI' then I alone can update the role of others in the Group.

This logic is working correctly as far as AA goes. If a non-PI user follows the link_to in the table, it certainly executes the block in the Ability class, and the controller will flash a notice that the action is not authorized. But it would be cleaner not to offer links to unauthorized pages in the first place. If I change the link_to line to:

para link_to "Edit Relationship", edit_admix_grouprelationship_path(gr.id) if can? :update, gr

then it throws the same undefined method error.

It is hard to find recent discussion of the can? method in AA. In older times e.g. this link, it seems it was necessary to modify the resource's controller with load_and_authorize_resource but this method does not exist in my AA controller.

So finally the question is how to configure the resource so that can? is enabled, or else what am I doing wrong?

There might be some complication because I am using a custom user model "admix_user" and namespace "admix" but I appear to have set this up correctly since CanCanCan authorization is working in every AA context except the above use of can?

Upvotes: 1

Views: 271

Answers (1)

Eli R.
Eli R.

Reputation: 188

reading the AA documentation, the correct usage is not can? but instead authorized?. i.e. in my controller the table displays correctly when I use

table_for resource.grouprelationships do
  column :action_test do |gr|
    para link_to "Edit Relationship", edit_admix_grouprelationship_path(gr.id) if authorized? :update, gr
 end
end

does the job. I was confused because of the conflicting documentation: here where can? is used and here where authorized? is defined.

Upvotes: 0

Related Questions