Rails 7控制器无法识别format.json请求求助
Rails 7 + Stimulus表格无数据:JSON请求未触发问题
我用Rails 7和Ruby 3.2.1开发应用,写了个OrderItemsController给Stimulus控制器提供数据,数据通过::DtfsOrders::OrderItemSerializer序列化后用于AgGrid表格展示,但表格完全没内容。我怀疑控制器有问题——在format.json块里加了binding.pry但程序根本没暂停,说明JSON请求根本没被识别到。
我的OrderItemsController代码
class OrderItemsController < ApplicationController def index # rubocop:disable Metrics/AbcSize, Metrics/MethodLength skip_policy_scope authorize(:order_item, :index?) @order_items_params = params.permit(:page).merge(limit: OrderItems::ListComponent::LIMIT) respond_to do |format| format.html do @order_item_list = fetch_order_items(@order_items_params.merge(limit: 1).to_h) end format.json do render json: fetch_order_items(@order_items_params.to_h) .serialize(::DtfsOrders::OrderItemSerializer, scope: view_context) .as_json end end rescue ::DtfsOrders::Error => e redirect_to root_path, alert: api_error_message(e) end private def api_error_message(error) = I18n.t('api_error', error: error.message, scope: 'order_items') def fetch_order_items(params) = FactoryBot.build(:dtfs_orders_order_item_list, :with_next_page, total_count: 1) def client = @client ||= ::DtfsOrders::Client.with_account(current_account) end
路由配置(routes.rb)
Rails.application.routes.draw do mount Rswag::Api::Engine => '/api-docs' mount Rswag::Ui::Engine => '/api-docs' mount Core::Engine, at: '/' resources :order_items, only: %i[index] end
补充:Stimulus控制器代码
import { Controller } from 'stimulus'; import Rails from '@rails/ujs'; import * as AgGrid from 'ag-grid-community'; import { DEFAULT_GRID_OPTIONS, buildColumnDefs, GridDatasource, updateColumnPositionsInCookies, } from 'core/utils/grid'; const columnOptions = { columnDefs: { order_reference: { cellClass: 'font-mono', cellRenderer: 'flexCellRenderer', sortable: false }, order_date: { cellClass: 'font-mono', maxWidth: 300, sortable: false }, description: { cellClass: 'font-mono', maxWidth: 300, sortable: false }, quantity: { cellClass: 'font-mono', maxWidth: 300, sortable: false }, amount: { cellClass: 'ag-right-aligned-cell font-mono', maxWidth: 200, sortable: false, headerClass: 'ag-header-cell ag-header-cell-sortable text-xs font-medium text-gray-500 uppercase bg-gray-100' + ' ag-focus-managed ag-right-aligned-header' }, currency: { cellClass: 'font-mono', maxWidth: 100, sortable: false }, vat: { cellClass: 'font-mono', maxWidth: 100, sortable: false }, actions: { cellClass: 'ag-right-aligned-cell font-mono', maxWidth: 120, sortable: false, withoutHeader: true }, }, cookiesName: 'order_items_columns_positions', defaultSorting: [ 'order_reference', 'order_date', 'amount', 'quantity', 'currency', 'vat', 'description', 'actions' ], }; function buildGrid(gridElement) { console.log('Building grid with element:', gridElement); const {indexUrl, paginationPageSize, i18nJson} = gridElement.dataset; console.log('indexUrl:', indexUrl); console.log('paginationPageSize:', paginationPageSize); console.log('i18nJson:', i18nJson); const options = { ...DEFAULT_GRID_OPTIONS, cacheBlockSize: paginationPageSize, maxConcurrentDatasourceRequests: 2, columnDefs: buildColumnDefs(columnOptions, i18nJson), datasource: new GridDatasource({ indexUrl }), onColumnMoved(params) { updateColumnPositionsInCookies(columnOptions, params) }, }; console.log('Options:', options); return new AgGrid.Grid(gridElement, options); } export default class extends Controller { connect() { const gridElement = this.element.querySelector('#order_itemsGrid'); if (gridElement) { this.gridObject = buildGrid(gridElement) } } disconnect() { if (this.gridObject) { this.gridObject.destroy(); } } }
可能的问题点及解决建议
- 请求格式不匹配:Stimulus的
GridDatasource可能没设置正确的请求头,导致Rails默认返回HTML而非JSON。可以在indexUrl后加上.json后缀(比如/order_items.json),或者检查GridDatasource的请求逻辑,确保带上Accept: application/json头。 - 路由被覆盖:你挂载了
Core::Engine在根路径,该引擎可能定义了同名路由,覆盖了你的order_items路由。执行rails routes命令查看实际生效的路由,确认order_items#index的JSON路由是否存在。 - 权限验证未捕获错误:
authorize(:order_item, :index?)触发的权限错误(比如Pundit的NotAuthorizedError)不在你的rescue捕获范围内,会直接中断请求,导致无法进入JSON响应块。可以暂时注释权限代码测试,或者添加对应的rescue逻辑。 - 测试数据序列化问题:
fetch_order_items返回的FactoryBot测试对象,其serialize方法可能没有生成符合要求的JSON结构。在Rails控制台手动调用fetch_order_items({}).serialize(::DtfsOrders::OrderItemSerializer, scope: view_context).as_json,查看输出是否包含表格所需字段。 - AgGrid数据源解析问题:检查
GridDatasource的实现,确认它能正确处理后端返回的JSON格式,比如是否期望数据包含items和total_count这类顶层字段,而你的序列化输出不符合该结构。
内容的提问来源于stack exchange,提问作者mr_muscle
相关产品推荐
相关产品推荐

