Dynamic Autocomplete in Rails 6
This walk-through demonstrates how to build a database-driven autocomplete field from scratch in Rails 6: 1

This sample feature will consist of a single input field that provides autocomplete suggestions from a PostgreSQL database. The suggestions will update on each keystroke. Clicking on a suggestion will take the user to a Google search for that name.
This tutorial assumes you have a fundamental understanding of Ruby on Rails, Javascript, and jQuery.
Table of Contents - Dynamic Autocomplete in Rails 6
A. System check ↑ Table of Contents
rails -v
:$ rails -v
Rails 6.0.2.2
ruby -v
:$ ruby -v
ruby 2.6.1p33 (2019-01-30 revision 66950)
You’ll need Ruby 2.5.0 or newer. Rails 6 will throw error messages if you don't have the correct Ruby version. I strongly recommend using a version manager like RVM or rbenv.
B. Create new application ↑ Table of Contents
$ rails new autocomplete --database=postgresql
$ cd autocomplete
$ rails db:create
rails s
and navigate to localhost:3000
in your web browser. You should see something like this:
C. Create model and controller ↑ Table of Contents
Next, we’ll create a bare bones Person
model and People
controller to handle the data that will eventually populate our autocomplete field.
Person
with first_name
and last_name
attributes:$ rails g model Person first_name last_name
Running via Spring preloader in process 46385
invoke active_record
create db/migrate/20200428174911_create_people.rb
rails db:migrate
to migrate the database:$ rails db:migrate
People
controller with an index
action (Rails automagically generates a corresponding view at app/views/pages/index.html.erb
):$ rails g controller People index
D. Seed database ↑ Table of Contents
We’ll need to put a few placeholder people
in the database for our autocomplete field to use later.
db/seeds.rb
:rails db:seed
:$ rails db:seed
Person.count
in the console should confirm that 4 people seeded into the database:> Person.count
(0.6ms) SELECT COUNT(*) FROM "people"
=> 4
Our app now has data for the autocomplete.
E. Create input field for autocomplete ↑ Table of Contents
The next step is to get Rails to display a simple input field when a user visits the homepage in a browser (localhost:3000
in development).
poeple#index
in config/routes.rb
:localhost:3000
, your GET request will trigger the index
action in app/controllers/people_controller.rb
. In turn, this should render the placeholder view that Rails generated at app/views/people/index.html.erb
when we created the controller earlier:
localhost:3000
This is where we’ll put our form input.
app/views/people/index.html.erb
. Replace, what’s there with a simple HTML search input, including a data-behavior
attribute set to autocomplete
. We’ll use this attribute later to identify this input as an autocomplete field:Note here that we are not generating an actual form — just an input. This is not normal. It is specific to this particular walk-through because (a) we’re going to use the autocomplete suggestions as links rather than submitting this form, and (b) handling form submissions is beyond the scope of what I want to cover here.
When you refresh your browser, you should now see a simple input at localhost:3000
:

F. Install jQuery ↑ Table of Contents
To help us make the autocomplete field interactive, we will add jQuery and a jQuery plugin called EasyAutocomplete. To less experienced Rails developers, this code may seem foreign. Don’t worry too much about understanding every line of code.
Installing jQuery is where Webpacker comes into play. Before Rails 6, you used to use a gem like jquery-rails
and //= require jquery
directions in a JS manifest file to add jQuery to a project with Sprockets.
No longer. With Webpacker, you add JS packages with Yarn, a JS package manager.
yarn add jquery
:$ yarn add jquery
yarn add v1.15.2
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
success Saved lockfile
success Saved 1 new dependency.
info Direct dependencies
﹂ jquery@3.5.0
info All dependencies
﹂ jquery@3.5.0
✨ Done in 6.63s.
config/webpack/environment.js
to tell Webpacker to include jQuery when it compiles our JS. The final file should look like this:This code came from here.
app/javascript/packs/application.js
:$().jquery
in the console:
jQuery is now installed in our Rails app through Webpacker.
G. Add EasyAutocomplete plugin ↑ Table of Contents
Now that jQuery is installed, we’re going to add a plugin called EasyAutocomplete. EasyAutocomplete will do most of the heavy lifting for our autocomplete field.
$ yarn add easy-autocomplete
yarn add v1.15.2
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
success Saved lockfile
success Saved 1 new dependency.
info Direct dependencies
﹂ easy-autocomplete@1.3.5
info All dependencies
﹂ easy-autocomplete@1.3.5
✨ Done in 6.34s.
For future reference, I’d also recommend bookmarking https://yarnpkg.com/. This page allows you to easily search for Yarn packages. This is how we know to use easy-autocomplete
in the yarn command above.
app/javascript/packs/application.js
:app/assets/stylesheets/application.css
:Note: if you’re using SCSS (this walkthrough is not), you would use this to import the necessary styles:
options
variable to an array of strings:
data-behavior
attribute and apply EasyAutocomplete's easyAutocomplete
method with the options
array we just defined:
There are a few details to notice here:
First, we are calling the form element by its data-behavior
attribute with jQuery. To understand what’s happening here, check out this StackOverflow thread.
Second, we are passing the options
variable we set above. This tells the autocomplete form to use the data values we gave it (e.g., John, Paul, George, and Ringo).
Third, you will notice that the formatting of the input field changes when we apply easyAutocomplete
. This is EasyAutocomplete's CSS kicking in.

You will notice that all names in the options
variable appear regardless of what we type in the input. We’ll fix this later when we start pulling in data dynamically.
Finally, we will move what we just did into code. This is a two step process: first we create a new JS file; and second, we import it with Webpacker.
app/javascripts/packs/people.js
and add the following code:Here, jQuery is telling the browser to: (1) wait until turbolinks finishes loading, (2) apply the easyAutocomplete
method to all inputs where the data-behavior
attribute equals autocomplete
, (3) and pass it the data stored in the options
variable.
options
variable in app/javascripts/packs/people.js
:
H. JSON payload ↑ Table of Contents
Our next goal is to prepare JSON so we can populate the autocomplete from the database.
search
action and apply a private before filter to force Rails to deliver JSON payloads:Person.first_name
or Person.last_name
:This search returns results based on params[:q]
, which is passed in through a variable in the GET request. (e.g., localhost:3000/people/search
) This example GET request will search for any record containing lick
(not case sensitive).
app/views/people/search.json.jbuilder
:This code will return a JSON array of strings. The strings will be in last_name, first_name
format.
localhost:3000?q=lick
, you should see this:
I. Data-driven autocomplete field ↑ Table of Contents
Now we will populate the autocomplete field from our database. EasyAutocomplete will do all the heavy lifting for us.
app/javascript/packs/people.js
with this:This code replaces the options
variable with an easyAutocomplete function that will (1) pull data via JSON using the controller action and view we created above, and (2) grab the name part of the JSON.
Notice how jQuery and EasyAutocomplete have abstracted all of the AJAX details? You don't need to worry about listening for keystrokes.

J. Handling the results ↑ Table of Contents
One last detail: what do we do when the user selects a result?
Let’s look at one obvious and simple option: directing the user to a Google search for the relevant person’s name.
app/views/people/search.json.jbuilder
to include a link to Google search results:Remember that this link needs to be URI-encoded, hence the call to CGI.escape
.

options
variable's template
attribute in app/javascript/packs/people.js
: 4

Congrats - you've reached the end of this tutorial. From here, you can easy modify easyAutocomplete to handle a number of useful tasks like updating database records, returning information, or reordering records on a page.
app/assets/javascript
are now managed with Webpacker and live at app/javascript
. To read more about the change from Sprockets to Webpacker, I recommend Prathamesh Sonpatki’s excellent article called Understanding Webpacker in Rails 6. ILIKE
fuzzy query in this tutorial.