Field extensions should not modify options hash
gael-ian opened this issue · 1 comments
Hello,
We are on our way to implement pre-authorization on fields in our GraphQL schema and on mutations in particular. We have quite a lot of them and, to reduce redundant declaration, we'd like to use the .with_options
method provided by ActiveSupport to merge options common to mutation field declarations around the same model.
Environment
Ruby Version: 3.2
Framework Version: Rails 7.1
Action Policy Version: 0.6.7
Action Policy GraphQL Version: 0.5.3
What did we do?
class Mutation < Types::Objects::Base
with_options preauthorize: { with: ThingPolicy } do
field :thing_create, mutation: Mutations::Things::Create
field :thing_update, mutation: Mutations::Things::Update
end
end
What did we expect to happen?
with_options
should work as expected and actually forward options to every .field
call.
What actually happened?
with_options
works as expected but field extensions consume options in a destructive way: as they internally use Hash#delete
on the options hash, the first field is correctly extended but subsequent fields receive empty options.
This can be fixed in a minimalist way with something like:
# In action_policy/graphql/authorized_field.rb
module ActionPolicy::GraphQL::AuthorizedField
class Extension < ::GraphQL::Schema::FieldExtension
+ def initialize(field:, options:) = super(field:, options: options&.dup || {})
+
def extract_option(key, &default)
value = options.fetch(key, &default)
options.delete key
value
end
end
end
Note: This will not be fixed in graphql-ruby. See rmosolgo/graphql-ruby#4733.
Thanks for the report and the suggested fix! Released in 0.5.4