使用 JSONAPI 资源按联接 table 的字段过滤

Filter by a field of a join table using JSONAPI Resources

我有三个table:

  1. 观察
  2. 子类别
  3. 类别

具有以下结构:

class Observation < ApplicationRecord
  translates :name
  belongs_to :subcategory
end

class Subcategory < ApplicationRecord
  belongs_to :category
  has_many :observations
end

class Category < ApplicationRecord
  has_many :subcategories
end

我希望能够使用 JSONAPI::Resource 过滤基于 category_id

的观察结果
class ObservationResource < JSONAPI::Resource
  attributes :name, :subcategory_id
  filter :subcategory_id, :test

  filter :test, apply: ->(records, value, _options) {
    records.where('subcategories.category_id = ?', value[0])
  }
end

如果我尝试执行请求:

/observations?include=subcategory,subcategory.category&filter[subcategory.category_id]=1

我得到:

subcategory.category_id is not allowed

如果我尝试执行请求:

/observations?include=subcategory,subcategory.category&filter[test]=1

我在尝试执行时收到来自 Postgres 的异常:

SQL (6.4ms) SELECT DISTINCT "observations"."id", "observations"."id" AS alias_0 FROM "observations" LEFT OUTER JOIN "observation_translations" ON "observation_translations"."observation_id" = "observations"."id" WHERE (subcategories.category_id = '1') ORDER BY "observations"."id" ASC LIMIT OFFSET [["LIMIT", 1000], ["OFFSET", 0]]

因为 table subcategories

上没有连接

如果我添加默认范围以包含 subcategories 所有查询都运行良好但最后一个失败,当尝试计算记录时:

SELECT COUNT(*) FROM "observations" WHERE (subcategories.category_id = '1')

我怎样才能正确地做到这一点?

当然,解决方案是使用“连接”:

filter :test, apply: ->(records, value, _options) {
  records.joins(:subcategory).where('subcategories.category_id = ?', value[0])
}