I'm using Pundit - and want to disable the ability...
# avo-2
f
I'm using Pundit - and want to disable the ability to attach, detach, and create associated records for almost every one of my tables. As a result, all of my policies are absolutely full of:
Copy code
def attach_user? = false
def detach_user? = false
def create_user? = false
Anyone know a nice way to make all of these relationship abilities
false
by default?
l
as they are Ruby classes, you should be able to do it with Ruby extensions
you'd still need to declare the association name
in the
ApplicationPolicy
create a class method that takes the association name (
user
) and have it create those methods dynamically
have a look at this recent PR https://github.com/avo-hq/avo/pull/1704/files
then, in the policy for a resource you could do something like
disable_association :user
and that method will do all this for you dynamically
Copy code
ruby
def attach_user? = false
def detach_user? = false
def create_user? = false
does that make sense?
f
I think so. I'm thinking I could use the @record inherited from the ApplicationPolicy, loop through all the associations, and define these methods
I'll need to see if I can get a list of all the available associations, given a record
l
you could do that too for a mre automated way, yes. I like to be a bit more in control, even if that requires me to manually add statements
to help with that you could use
Avo::App.get_resource_by_model_name("MODEL_NAME")
and go through the
fields
. the
field.type
will be
belongs_to
,
has_many
, etc.
those will be the fields you declared on the resource
f
Oooooh. That is super super useful, thank you. That saved me a bunch of time digging
You've given me a great head start, thank you very much! I'll say what I ended up doing here in a bit 🙂
l
thanks!
f
Ended up pretty much copying the example from the PR you linked:
Copy code
ruby
module Avo
  module Concerns
    module PolicyHelpers
      extend ActiveSupport::Concern

      class_methods do
        def disable_association_management(association_name)
          %i[attach detach create].each do |method_action|
            define_policy_method(method_action, association_name)
          end
        end

        private

        # Define a method for the given action and association name.
        def define_policy_method(method_action, association_name)
          define_method "#{method_action}_#{association_name}?" do
            false
          end
        end
      end
    end
  end
end
Works great!
Like you were originally suggesting, I still have to call it for each association but thats fine.
l
amazing!
thanks for sharing!