1

I get a strange error when trying to run a global autocomplete search across multiple models in my rails App and leveraging the easy-autocomplete jquery library along with the ransack gem for search.

Specifically, I believe the error is in my navbar page as I get this error when I try to run a query- undefined method form_with for #<#<class:0x007f875a6f8b58>:0x007f87600e0aa8>

I decided to hack away and switch form_with for form_tag but then I get an error on the line immediately below undefined method text_field for nil:NilClass" I have listed all my relevant code below. Thank you so much for any help.

Main_Controller.rb

class MainController < ApplicationController
def index
end
def search
@movies    = Movie.ransack(name_cont: params[:q]).result(distinct: true)
@directors = Director.ransack(name_cont: params[:q]).result(distinct: true)

respond_to do |format|
  format.html {}
  format.json {
    @movies    = @movies.limit(5)
    @directors = @directors.limit(5)
  }
end
end
end

_navbar.html.erb

<%= form_with url: search_path, local: true, method: :get, html: { class: "form-inline my-2 my-lg-0" } do |form| %>
  <%= form.text_field :q, placeholder: "Search", data: { behavior: "autocomplete" }, class: "form-control mr-sm-2" %>
  <%= form.button "Search", class: "btn btn-outline-success my-2 my-sm-0" %>
<% end %>

search.html.erb

<div class="row">
<div class="col">
<h1>Movies</h1>
<% @movies.each do |movie| %>
  <p><%= link_to movie.name, movie %></p>
<% end %>
</div>
<div class="col">
<% @directors.each do |director| %>
  <p><%= link_to director.name, director %></p>
<% end %>
</div>
</div>

search.js

document.addEventListener("turbolinks:load", function() {
$input = $("[data-behavior='autocomplete']")
var options = {
getValue: "name",
url: function(phrase) {
  return "/search.json?q=" + phrase;
},
categories: [
  {
    listLocation: "movies",
    header: "<strong>Movies</strong>",
  },
  {
    listLocation: "directors",
    header: "<strong>Directors</strong>",
  }
],
list: {
  onChooseEvent: function() {
    var url = $input.getSelectedItemData().url
    $input.val("")
    Turbolinks.visit(url)
  }
}
}
$input.easyAutocomplete(options)
});
Omar
  • 383
  • 3
  • 17
  • 2
    If you replace form_with by form_tag, just make sure you remove |form| after do. And the same way replace "form.text_field" by "text_field_tag" – Maxence Jun 15 '17 at 22:11
  • Actually you use form_with as a mix of form_for and form_tag and it is conflicting. Because your form_with has no object or variable associated to it, only a link. – Maxence Jun 15 '17 at 22:13
  • @Maxence, thank you so much for responding, really appreciate it. A bit lost because of your second answer - it is only a link as my search.js is leveraging JSON and URL when the query runs. – Omar Jun 16 '17 at 16:44
  • 1
    Sorry for that. What I meant is that your form_with only has a link to the desired controller. It has no object such as :search or an instance variable such as @search. In this case you should use tag helpers inside the form body (such as text_field_tag or submit_tag) You should read this : http://guides.rubyonrails.org/form_helpers.html#binding-a-form-to-an-object and you will understand the difference between form_for and form_tag (form_with is the new syntax in Rails 5.1+ that group both helpers) – Maxence Jun 16 '17 at 16:52
  • 1
    in the case of your search form, there is no need to apply an object or instance variable, so you should use form_with like if it was a good old form_tag. You canot create a |form| temporary constant in this case as there is no `search` model in your database structure. – Maxence Jun 16 '17 at 17:07

1 Answers1

8

In your gem file change rails gem to the latest: gem 'rails', '~> 5.1.1' or higher consol: bundle update Restart your rails application Hope this works for you

Charlie
  • 236
  • 2
  • 13