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
相关产品推荐
相关产品推荐

