- Notifications
You must be signed in to change notification settings - Fork 2.3k
CanCan: remove associated action buttons in forms
Help: i dont feel too confident about my ruby-skills. Please help improving this article by improving the source where needed, thanks
In order to remove the "Add new"/"Edit" buttons for associated Models in the form without removing the ability to manage those associated models, cancan helps out well.
Example: a User can :manage Authors and Books, but must not be able to :manage authors while in Books-Edit form
The idea is pretty simple:
cannot [:create,:update], Model unless current_model == Model
The default CanCan AuthorizationAdapter however does not inform the Ability-Class about the current view/model, that is why it needs to be overwritten.
mkdir -p lib/rails_admin/extensions/cancan/ cd lib/rails_admin/extensions/cancan/; wget https://raw.github.com/gist/3302673/7d013f23bba67a7c7317003c56117b2a88503d39/authorization_adapter.rb
This file, contains the ControllerExtension-Module, cloned from RailsAdmins original CanCan AuthorizationAdapter, except for the 2nd Parameter in @ability.new, which represents the current displayed model you want to edit.
This gist contains:
module RailsAdmin module Extensions module CanCan class AuthorizationAdapter private module ControllerExtension def current_ability @current_ability ||= @ability.new(_current_user, self.params["model_name"]) end end end end end end
the CanCan configuration will remain the same, except for loading the updated authorization_adapter.rb.
require Rails.root.join('lib/rails_admin/extensions/cancan/authorization_adapter') RailsAdmin.config do |config| ....
I load the authorization_adapter here, since i find it belongs to rails_admins configuration, which i dont want to have "all over the app".
The only mandatory update is to add a further parameter to the initialize method, named like request_model. It is the Model-Class you are viewing,editing in RailsAdmin.
My Example from above was: "a User can :manage Authors and Books, but should not be able to manage Autors while in Books-Edit form"
this can result in something like:
class Ability include CanCan::Ability def initialize(user, request_model) if user can :access, :rails_admin can :dashboard can :manage, :all # For all Models we have, forbid create and update # but dont forbid :manage, in order to keep it in # navigation if not excluded by rails_admin config ActiveRecord::Base.descendants.each do |m| cannot [:create, :update], m unless request_model == m.name.underscore end if request_model # a manual way can look like this : # cannot [:create, :update], Author if request_model == "books" # cannot [:create, :update], Book if request_model == "author" else cannot :access, :rails_admin end end end
Thats it, now the Edit/Create associated Model-buttons are gone, but the Model remains in the Navigation. This is quite usefull if a User may create associations with models which are excluded via rails_admin config