0

I'm trying to use ajax for displaying searching results in a Ruby on rails app. However, after I submit the search form, it shows ActionController::UnknownFormat error at the line where it says respond_to respond_to do |format|. It does not allow me render partial and I'm not sure why. Using Rails 6.0.2.2

availabilities/_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>

part of 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

availabilities/search.html.erb

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

availabilities/_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 %>

availabilities/_result.js.erb

alert("hello world!")

1 Answer 1

1

You have fundamentally misunderstood how Rails UJS works. When you use remote: true Rails UJS sends an XHR request to Rails with a application/javascript content type. Rails renders some JavaScript (or what should have been js) and then sends it back to the client.

Rails UJS takes the response and essentially pops it into a script tag to eval it. If the response is a bunch of HTML this will just cause a parser error.

What you want to do is:

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

Then create a js.erb view containing JavaScript that alters the existing DOM:

// app/views/availabilites/results.js.erb
document.getElementById("results")
        .innerHTML = "<%= j render(partial: 'results.html.erb') %>";
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your explanation! I wasn't really understanding how ajax works. However, there is still respond_to format known error after revision, so I added respond_to :js on the top of the controller so that js can be in the whitelist. But the problem is that after I hit search button, it still stays on the search form page and reports that permitted is false. I'm not quite understanding the reason.
Did you check the logs so that the request is actually sent for JS? If not check the console in the browser for errors that are messing up Rails UJS.
The permitted false thing is most likely because you are mass assigning params[:search] without whitelisting it with strong paramaters
I have a search_params function which I didn't include in the above post for whitelisting it with strong parameters. It seems that after submitting the form the search function is never triggered. I'll check again for request.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.