首页 > 解决方案 > 根据 graphql-ruby 中的解析器参数更改类型字段的值

问题描述

我正在尝试计算类型的字段值,但我必须考虑用户(查询)传递给我的解析器的参数。

一个虚拟的例子:

假设我的 rails 应用程序中有两个模型:DogPrice(狗的has_many价格,取决于它的颜色)。所以我有一个计算字段DogTypefield :price, Float, null: true我在哪里object.prices.minimum(:price),到目前为止一切都很好。

但是当用户allDogs使用参数查询时color: black(为了只列出黑狗),我不希望我的计算字段price返回所有狗的错误价格,所以我必须考虑到我的过滤器解析器,因此也过滤类型中的价格。

我的问题很重要,graphql-ruby但我对如何使用 GraphQL 样板解决此类问题很感兴趣:如何正确了解对象类型,解析器应用了哪些过滤器?

我按照这个学习进行过滤,所以我的解析器看起来像这样:

class Resolvers::DogsSearch < Resolvers::Base
  # scope is starting point for search
  scope { Dog.all }

  type types[Types::DogType]

  # inline input type definition for the advance filter
  class DogFilter < ::Types::BaseInputObject
    argument :color_id, ID, required: false
  end

  # when "filter" is passed "apply_filter" would be called to narrow the scope
  option :filter, type: DogFilter, with: :apply_filter

  def apply_filter(scope, value)
    if value[:color_id]
     # here's my take on how to do this : I store the filter in the context so I may access it later
     context[:color_id] = value[:color_id]
     self.scope = scope.where('color_id = ?', value[:color_id])
    end
  end
end
module Types
  class DogType < Types::BaseObject
    field :color_id, ID, null: false
    ...

    field :price, Float, null: true

    def price
      # I have to retrieve filter from context if any
      if context[:color_id]
        Price.where(dog: object, color_id: context[:color_id]).minimum(:price)
      else
        object.prices.minimum(:price)
      end
    end
  end
end

module Types
  class QueryType < BaseObject
    field :all_dogs, resolver: Resolvers::DogsSearch
  end
end

这可行,但似乎效率很低,不是 Rail 的方式,而且绝对容易出错。我必须在我的应用程序的多个地方执行此操作,并且担心它无法很好地扩展。

有没有官方的处理方式?

为了理解,我简化了我所面临的真实示例,但我认为我的核心问题在于这个。

标签: ruby-on-railsgraphqlgraphql-ruby

解决方案


推荐阅读