【问题标题】:j(render(@partial)) returns error: ActionController::UnknownFormatj(render(@partial)) 返回错误:ActionController::UnknownFormat
【发布时间】:2015-02-15 16:11:18
【问题描述】:

我正在尝试使用 ajax 渲染部分,但由于某种原因它返回此错误:

ActionController::UnknownFormat in ThingsController#upvoterandom
ActionController::UnknownFormat

我很困惑,因为我以前用基本相同的格式完成了一些事情,而且我从来没有遇到过任何问题。有人看到我的代码有什么问题吗?我可以用 ajax 渲染一个字符串;只有当我尝试渲染部分时,我才会收到错误。顺便说一句,我通过删除format.html这一行然后直接在我的浏览器中访问upvoterandom_thing路径实现了这个错误。

views/things/show.html.erb

<div id= "randomajax" >
    <div id="randajax">
      <%= link_to @rand.name, thing_path(@rand) %>
      <%= link_to image_tag("UpArrowGray.jpg", class: "rand_up_vote"), remote: true, %>
      <script type="text/javascript">
        function reload_script() {
            $(".rand_up_vote").click(function () {
              $.get( "<%= upvoterandom_thing_path(:id => @rand.id) %>", function( data ) {
              });
            });
        }
        reload_script();
      </script> 
    </div>
</div>

controllers/things_controller.rb我在错误突出显示的行周围加上了星号。

def upvoterandom
  @thing = Thing.find(params[:id])
  #...
  ***respond_to do |format|***
    format.html { redirect_to root_path }
    format.js
  end
end

views/things/upvoterandom.js.erb: .html("test") 返回“test”,所以问题一定出在渲染上。

$('#randomajax').html("<%= j(render(@randajax)) %>");

views/things/_randajax.html.erb

TEST

这是另一种几乎相同的 AJAX 结构:


views/things/show.html.erb

<%= form_for([@thing, @comment], remote: true) do |f| %>
  <%= f.text_area :text %>
  <%= f.submit "Post", id: "postacomment" %>
<% end %>

controllers/cmets_controller.rb

def create
  @thing = Thing.find(params[:thing_id])
  @comment = @thing.comments.create(comment_params)
  respond_to do |format|
    format.html { redirect_to root_path }
    format.js
  end
end

views/cmets/create.js.erb

$('#comments_h2').prepend("<%= j(render(@comment)) %>");

views/cmets/_comment.html.erb

TEST

【问题讨论】:

    标签: javascript ruby-on-rails ruby ajax ruby-on-rails-4


    【解决方案1】:

    我会为冗长的答案提前道歉。我已尝试以多种方式重现您的问题,但我认为您可能看错了方向。我已经包含了整个故事,因此您可以查看它是否都匹配,如果不匹配,它希望能带来有助于您解决问题的见解。

    ActionController::UnknownFormat 发生在视图渲染之前

    如果 Rails 向您显示 ActionController::UnknownFormat 错误,这意味着您的控制器没有响应所请求的格式。错误是由respond_to 方法引发的,位于您突出显示的确切行。

    如果在视图渲染过程中出现错误,那么它将通过format.html 或format.js 的行冒泡。所以这个错误肯定不是视图渲染部分造成的。

    重现ActionController::UnknownFormat 错误

    如果我直接在浏览器中请求 AJAX 响应页面,我可以获得您发布的确切错误消息的唯一方法。然后您会看到 Rails 错误页面,该页面还将显示请求是使用哪种格式完成的。您可能请求的页面格式不是html 或js,在这种情况下会触发ActionController::UnknownFormat 错误,因为您的控制器仅 响应html 或@ 987654331@格式。

    我认为实际问题隐藏在其他地方。

    从views/things/show.html.erb复制

    我也尝试从views/things/show.html.erb 页面重现错误。使用您的原始代码执行此操作时,我在以下行收到语法错误:

    <%= link_to image_tag("UpArrowGray.jpg", class: "rand_up_vote"), remote: true, %>
    

    这是由于remote: true 后面的逗号造成的。因此,我假设您没有一直在使用远程链接进行测试。在没有remote: true 的情况下对其进行测试时,reload_script 函数会触发一个 jQuery AJAX 请求。您正在使用以下行执行此操作:

    $.get( "<%= upvoterandom_thing_path(:id => @rand.id) %>", function( data ) {
    });
    

    这实际上触发了格式为*/* 的XHR 请求。它基本上告诉 Rails 任何格式都可以。以下是发生的事情:

    1. ThingsController 以您在respond_to 块中定义的第一种格式进行响应,这是 HTML 格式。这会触发重定向到您的根路径。
    2. jQuery 遵循重定向,再次使用*/* 格式。
    3. 如果没有respond_to 块,则根路径中的控制器会以第一个定义的格式或默认HTML 响应。
    4. jQuery 然后加载该响应。

    当像这样复制 ActionController::UnknownFormat 时,不可能从 ThingsController 提升它。

    我的想法

    这主要是猜测工作,所以如果我错了,请纠正我:

    1. 您单击了远程投票链接,但没有明显发生任何事情。
    2. 您添加了一个 JavaScript 以通过 AJAX 显式获取页面,但仍然没有明显发生任何事情。
    3. 您直接使用浏览器访问了things/1/upvoterandom.js(或类似)页面。在这种情况下,ActionController::InvalidCrossOriginRequest 将被提出。
    4. 您直接使用浏览器访问了things/1/upvoterandom.json(我使用了JSON,但它可以是HTML 或JS 以外的任何格式)页面,并收到ActionController::UnknownFormat 错误。

    如果是这样,您需要返回到第 1 步,并开始从另一个方向重现问题:

    1. 转到things/1(或其他事物 ID)页面。
    2. 打开浏览器的开发者工具/Web Inspector。
    3. 转到显示网络通信的视图(在 Chrome 中,这是名为 Network 的选项卡)。
    4. 现在单击链接,看看您的浏览器和 Rails 应用程序之间发生了什么通信。如果发生很多情况,您通常可以只过滤 XHR,它只显示 AJAX 请求。
    5. 如果您看到那里弹出 500 状态,则需要使用堆栈跟踪检查 Rails 服务器输出是否有错误。

    我只能猜测问题的实际原因是什么,但我认为在渲染视图时实际上可能是一些错误,正如你所说,它不起作用的唯一情况是渲染部分。我希望这些信息可以帮助您解决问题。

    【讨论】:

    • 我不知道这是否正确,但这是很棒的侦探工作。
    • 我发现我可以只使用 ruby​​ 来渲染部分而不是 javascript。但无论如何我都会奖励你,因为正如 pjmorse 所说,这是一项伟大的侦探工作。你已经死心塌地的假设了。
    【解决方案2】:

    在views/things/upvoterandom.js.erb 中,您尝试像这样渲染@randajax:

    $('#randomajax').html("<%= j(render(@randajax)) %>");
    

    但我没有看到 @randajax 被分配到任何地方,这意味着它是 nil。

    尝试渲染 nil 是导致此问题的原因。但请首先执行以下操作来确认这一点:

    $('#randomajax').html("<%= j(render(nil)) %>");
    

    如果它返回相同的错误,那么我们找到了罪魁祸首。

    在渲染之前分配 @randajax 或者简单地使用:

    $('#randomajax').html("<%= j(render(path_to_partial)) %>");
    

    【讨论】:

      【解决方案3】:

      好吧,我还没有弄清楚为什么我尝试的语法不起作用,但这个语法确实有效:

      $('#randomajax').html("<%= render 'randajax' %>");
      

      【讨论】:

      • 这不是我提供的相同答案吗?
      • 我什至不知道switched to ruby instead of javascript 是什么意思。在此版本中,您根本没有对 JavaScript 进行转义,而是为 render 方法提供了部分路径,而不是 nil 值。
      • 我试过你的语法,但没有用。我使用的是 ruby​​ 渲染方法而不是 j(render),我认为它是 javascript(render) 的缩写。
      • 不。 'j' 是 'escape_javascript' 的别名,您可以在此处阅读:api.rubyonrails.org/classes/ActionView/Helpers/… 按照该链接查看j(render(view_path)) 时如何处理某些字符。由于您通过 JavaScript 的 html() 函数呈现输出,因此您实际上可能需要 j(render 而不仅仅是 render。我正在为您以及未来偶然发现这里的搜索者澄清这一点。我很好奇:我的回答是否仍然返回 ActionController::UnknownFormat 错误?
      • 啊,我明白了。然后我不知道为什么你的语法不起作用。是的,它返回相同的错误。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-21
      相关资源
      最近更新 更多