【问题标题】:Rails API route Resources wrong responseRails API 路由资源错误响应
【发布时间】:2021-01-18 07:15:19
【问题描述】:

我有一个在 Ruby 2.6.6 上运行的 Ruby on Rails 5.2.4。前端期望后端返回的数据是一个 JSON 结构:“resources”(如果有数据列表)或“recource”,如果只有一个数据。

该应用程序是为 Rails 5.0 创建的,我进行了一些更新,因此它也可以在 Rails 5.2 上正常运行。也许我错过了什么。

routes.rb 看起来像:

resources :route_a, only: [:index, :show]
resources :route_b, only: [:index]
resources :route_c, only: [:create]
resource  :route_d, only: [:create, :update, :destroy]
...
resources :route_e, only: [] do
  resource :route_f, only: [] do
    post 'route_g', on: :member
  end
end

前端 Javascript 框架期望返回的数据包含“资源”或“资源”键。但在 80% 的情况下,数据不会返回资源/资源结构化 JSON。 Rails 有什么问题?这个问题与 gem 或数据库有关吗?为什么对于某些路由,响应以资源/资源结构化数据返回,而对于其他路由,则返回纯 JSON?

回复如下:

[{"id":33,"type":"M..

我需要:

[{"resources":{"id":33,"type":"M...

我是 Rails 新手,很抱歉可能会问一些基本问题,但我不知道这里有什么问题。谢谢。

重要

我有一个文件:config/initializers/wrap_parameters.rb,其中包含:

# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
ActiveSupport.on_load(:action_controller) do
  wrap_parameters format: [:json]
end

# To enable root element in JSON for ActiveRecord objects.
# ActiveSupport.on_load(:active_record) do
#   self.include_root_in_json = true
# end

重要2

这是/api/integrations 页面控制器:

class IntegrationsController < ApiController

def index
    integrations = policy_scope(Integration)
    integrations = integrations.where(type: params[:type_eq]) if params[:type_eq]
    render_resources integrations, ransack_query: params[:q]
  end
end

api/integrations 的响应是:

[{"id":254,"name":"Integration 1"...

结果中不包含任何resources 键。我在下面描述了render_resources 方法:

def render_resources(resources, options = {})
    options[:pagination] = true if options[:pagination].nil?
    pagination = options.delete(:pagination)
    ransack_query = options.delete(:ransack_query) || {}
    ransack_sort = options.delete(:ransack_sort) || params[:sort]

    resources = resources.ransack(ransack_query.to_hash.merge(s: ransack_sort)).result if ransack_sort || ransack_query.any?

    total = resources.respond_to?(:total_count) ? resources.total_count : resources.length
    default = {root: :resources, meta: {total: total}}
    results = pagination ? resources.page(params[:page]).per(params[:per_page]) : resources
    results = results.includes(options[:includes]) if options[:includes]
    render({json: results}.merge(default).merge(options))
  end

由于此方法不再返回包含 resources 键的响应,我是否可以说这是因为隐含的库 - Ransack 和 Pagination?因为在我更新 ruby​​ 和 rails gems 之前,这些功能都按预期工作。不过,我不知道应该在 resourcesresource 键中构造响应的 JSON 数据的库是什么。

【问题讨论】:

  • 我怀疑您正在使用 ActionModelSerializers 或类似的东西,并且更新中发生了一些变化。我建议检查资源结构是否发生了变化(例如新的/缺失的键)。除此之外,尝试将render_resource 的最后一行更改为render {json: {resources: results, meta: {total: total}}}.merge(options)
  • 我会检查的。感谢您的建议!

标签: ruby-on-rails ruby rubygems ruby-on-rails-5 ruby-on-rails-5.2


【解决方案1】:

如果您直接从 rails 5.0 升级到 5.2,您可能会跳过修复 5.1 中存在的一些弃用警告。 ruby 升级的情况相同 - 除非您有大量的测试覆盖并且一切正常 - 最好一次升级一个次要 (5.0->5.1->5.2) 版本。

在 rails 升级期间,其他 gem 也会升级,每个 gem 的每个新版本都可能有一些重大更改(或新错误)

如果您正在使用 active_model_serializers - 您可能会受到它们对默认适配器 (now it's json_api) 的更改以及围绕 root 选项的其他移动的影响,请参阅 changelog for 0.10 和以前的更改日志,具体取决于您的版本升级自

【讨论】:

  • 另外,将 gem 的版本锁定到 5.0 的版本可能会有所回报,然后尝试先将 Rails 升级到 5.1,然后依次升级每个 gem。
  • 我相信我犯了从5.0升级到5.2.4.2(最新)的错误。正如您在回复中指出的那样,我将检查 0.10 的更改日志。非常感谢!
  • Rails 不遵循标准 SemVer。补丁级别更新需要一些工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多