You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby on Rails中ActionController::UnknownFormat错误(AJAX场景)

问题排查与解决方案

核心问题分析

  • 不加data: {turbo: false}时,Rails 7默认的Turbo会发送Turbo Stream格式请求,但控制器未处理该格式,因此页面无反应;
  • 添加该属性后,表单恢复为普通HTML请求,而控制器仅定义了format.js响应,没有匹配的HTML格式处理逻辑,触发ActionController::UnknownFormat错误。

具体解决方法

方法1:适配Turbo(推荐,符合Rails 7生态)

无需禁用Turbo,通过以下两种方式调整:

方式A:添加Turbo Stream响应支持

修改控制器,加入Turbo Stream格式处理,并创建对应的模板文件:

class StocksController < ApplicationController
  def search
    if params[:stock].present?
      @stock = Stock.new_lookup(params[:stock])
      if @stock
        respond_to do |format|
          format.turbo_stream
          format.js { render partial: 'users/result' }
        end
      else
        flash[:alert] = "Please enter a valid symbol to search"
        redirect_to my_portfolio_path
      end
    else
      flash[:alert] = "Please enter a symbol to search"
      redirect_to my_portfolio_path
    end
  end
end

创建app/views/stocks/search.turbo_stream.erb模板,用于无刷新更新页面内容:

<%= turbo_stream.update 'search-results-container' do %>
  <%= render partial: 'users/result', locals: { stock: @stock } %>
<% end %>

注意:需要在页面中添加目标容器,比如在搜索区域下方加入<div id="search-results-container"></div>。

方式B:让表单发送JS格式请求

在form_tag中添加data: { type: :js },让请求直接匹配控制器的format.js:

<div class="search-area">
  <h3>Search Stocks</h3>
  <%= form_tag search_stock_path, data: { type: :js }, method: :get do %>
    <div class="form-group row">
      <div class="col-sm-9 no-right-padding">
        <%= text_field_tag :stock, params[:stock], placeholder: "Stock ticker symbol", autofocus: true, class: "form-control form-control-large"%>
      </div>
      <div class="col-sm-3 no-left-padding">
        <%= button_tag type: :submit, class: "btn btn-success" do %>
          <%= fa_icon 'search 1.5x' %>
        <% end %>
      </div>
    </div>
  <% end %>
</div>

方法2:禁用Turbo并补充HTML响应(不推荐)

如果坚持禁用Turbo,需要在控制器中补充HTML格式的响应逻辑,避免格式错误:

class StocksController < ApplicationController
  def search
    if params[:stock].present?
      @stock = Stock.new_lookup(params[:stock])
      if @stock
        respond_to do |format|
          format.js { render partial: 'users/result' }
          format.html { redirect_to my_portfolio_path, notice: "Stock retrieved successfully" }
        end
      else
        flash[:alert] = "Please enter a valid symbol to search"
        redirect_to my_portfolio_path
      end
    else
      flash[:alert] = "Please enter a symbol to search"
      redirect_to my_portfolio_path
    end
  end
end

此方式会失去AJAX无刷新的效果,不符合现代Rails开发的最佳实践。

额外检查点

  • 确保app/views/users/_result.js.erb存在(若使用format.js渲染),文件需包含JS更新逻辑,示例:
    $("#search-results-container").html("<%= j render 'users/stock_info', stock: @stock %>");
    
    其中j是escape_javascript的简写,用于避免JS语法错误,_stock_info.html.erb是展示股票信息的HTML partial。
  • 确认路由配置正确:
    # config/routes.rb
    get 'search_stock', to: 'stocks#search'
    

内容的提问来源于stack exchange,提问作者sheredega

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 18:01:28