【问题标题】:respond_to do |format| format.js not working (ruby on rails & ajax)respond_to 做 |格式| format.js 不工作(ruby on rails & ajax)
【发布时间】:2020-07-08 20:55:04
【问题描述】:

我正在尝试使用 ajax 在 Ruby on rails 应用程序中显示搜索结果。但是,在我提交搜索表单后,它会在显示 respond_to respond_to do |format| 的那一行显示 ActionController::UnknownFormat 错误。它不允许我渲染部分,我不知道为什么。 使用 Rails 6.0.2.2

可用性/_searchform.html.erb

<form>
    <%= simple_form_for(:search, :url => search_rides_path, :remote => true, :method => :get) do |f| %>
        <div class="form-row">
            <div class="form-group col-md-2">
                <%= f.input :start_city, label: 'Start City', class: "form-control", error: 'Start address is mandatory, please specify one' %>
            </div>
            <div class="form-group col-md-4">
                <%= f.input :start_street_address, label: 'Start Street Address', class: "form-control" %>
            </div>
        </div>
        <div class="form-row">
            <div class="form-group col-md-2">
                <%= f.input :end_city, label: 'Destination City', class: "form-control" %>
            </div>
            <div class="form-group col-md-4">
                <%= f.input :end_street_address, label: 'Destionation Street Address', class: "form-control" %>
            </div>
        </div>
        <div class="form-row">
            <div class="form-group col-md-2">
                <%= f.input :trip_date, as: :date, html5: true, inline_label: 'Yes, remember me', class: "form-control" %>
            </div>
            <div class="form-group col-md-2">
                <%= f.input :trip_time, as: :time, html5: true, inline_label: 'Yes, remember me', class: "form-control" %>
            </div>
            <div class="form-group col-md-2">
                <%= f.input :lowest_acceptable_price, label: 'Expected Price', class: "form-control" %>
            </div>
        </div>
            <%= f.submit "Search", class: "btn btn-primary" %>
    <% end %>
</form>

avilabilities_controller.rb 的一部分

class AvailabilitiesController < ApplicationController
  before_action :set_availability, only: [:show, :edit, :update, :destroy]
  # respond_to :html, :json, :js
  # GET /availabilities
  # GET /availabilities.json
  def index
    @availabilities = Availability.unmatched
  end

  def search
    if params[:search]
      @availabilities = Availability.unmatched.search(params[:search])
      if @availabilities
        respond_to do |format|
          format.js { render partial: 'availabilities/result.html'}
        end
      else
        respond_to do |format|
          flash.now[:alert] = "Could not find an availability"
          format.js { render partial: 'availabilities/result.html'}
        end
      end
    else
      @availabilities = Availability.unmatched
    end
  end
end

可用性/search.html.erb

<p id="notice"><%= notice %></p>
<%= render 'searchform' %>
<div id="results">
</div>

可用性/_result.html.erb

<% if @availabilities %>
    <%@availabilities.each do |availability|%>
          <div class="card" style="width: 18rem;">
            <div class="card-body">
                <h5 class="card-title">Ride</h5>
                <strong>Start city: </strong> <%= availability.start_city %><br>
                <strong>Start street address: </strong><%= availability.start_street_address %><br>
                <strong>End city: </strong><%= availability.end_city %><br>
                <strong>End street address: </strong><%= availability.end_street_address %><br>
                <strong>Trip Time: </strong><%= availability.trip_time %><br>
                <strong>Price Requested: </strong><%= availability.lowest_acceptable_price %><br>
                <br>
                <a href="#" class="btn btn-primary">View Details</a>
                <a href="#" class="btn btn-primary">Request Ride</a>
            </div>
        </div>
    <% end %>
  </div>
<% else %>
    <h1> No results have been found </h1>
<% end %>

可用性/_result.js.erb

alert("hello world!")

【问题讨论】:

    标签: ruby-on-rails ajax


    【解决方案1】:

    您从根本上误解了 Rails UJS 的工作原理。当你使用remote: true Rails UJS 向Rails 发送一个带有application/javascript 内容类型的XHR 请求。 Rails 渲染一些 JavaScript(或者应该是 js),然后将其发送回客户端。

    Rails UJS 获取响应并将其弹出到脚本标签中以对其进行评估。如果响应是一堆 HTML,这只会导致解析器错误。

    你想做的是:

    class AvailabilitiesController < ApplicationController
      before_action :set_availability, only: [:show, :edit, :update, :destroy]
      # respond_to :html, :json, :js
      # GET /availabilities
      # GET /availabilities.json
      def index
        @availabilities = Availability.unmatched
      end
    
      def search
        if params[:search]
          @availabilities = Availability.unmatched.search(params[:search])
          respond_to do |format|
            flash.now[:alert] = "Could not find an availability" unless @availabilities.any?
            format.js { render :result  }
          end
        else
          @availabilities = Availability.unmatched
        end
      end
    end
    

    然后创建一个 js.erb 视图,其中包含更改现有 DOM 的 JavaScript:

    // app/views/availabilites/results.js.erb
    document.getElementById("results")
            .innerHTML = "<%= j render(partial: 'results.html.erb') %>";
    

    【讨论】:

    • 感谢您的解释!我并没有真正理解 ajax 是如何工作的。但是修改后还是有respond_to格式已知的错误,所以我在controller的顶部添加了respond_to :js,这样js就可以在白名单里了。但问题是,在我点击搜索按钮后,它仍然停留在搜索表单页面上并报告“允许”为假。我不太明白原因。
    • 您是否检查了日志以便实际为 JS 发送请求?如果不检查浏览器中的控制台是否有弄乱 Rails UJS 的错误。
    • 允许的错误很可能是因为您大量分配 params[:search] 而没有使用强参数将其列入白名单
    • 我有一个 search_params 函数,我没有包含在上面的帖子中,用于将它与强参数列入白名单。似乎在提交表单后,搜索功能永远不会被触发。我会再次检查请求。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-05
    • 2023-04-08
    相关资源
    最近更新 更多