DEV Community

Cover image for Tutorial: Build a Yelp Dynamic Search with Ruby on Rails
Stephanie Zou
Stephanie Zou

Posted on

Tutorial: Build a Yelp Dynamic Search with Ruby on Rails

I came across an interesting problem while working on a coding project. The goal was to implement a feature, using Ruby on Rails, that resembled the Yelp search bar. How do we build it out such that the user could find an activity by searching not only its name or organization but any keyword or even its zip code? On top of that, if the user miscapitalizes the activity or adds in a random white space in the middle of the word, how do we produce the desired search results?

This post will walk you through, step-by-step, how we can create a dynamic search field that fulfills all of the desired features mentioned above.

Step 0. the setup

To start off with some context, we want the user to be able to filter through all the activities in the database so I’m writing the code in my activities controller under the index method where we can also format the page to look like a standalone search bar (I’ll go more into detail about that). If you want to see the project code for reference, check out my GitHub repo here.

GitHub logo stephaniezou1 / Acorn-Search-Engine

Yelp, but designed to help families find affordable after school activities 📚

.

The search bar itself will interact with the user through the activities > index view page.

Note, in my HTML file, I built out a form_tag so that when a user types in and submits a search term into the form, it’s saved in params with the key [:search].

Step 1. create a search variable

From here, we know that we can assign params[:search] to a variable and start playing around with it in our activities controller to create our desired search bar.
Let’s store params[:search] in the variable search_term and initialize @activities as Activity.all

Step 2. set up search features

Now back to first principles. What do we want to accomplish here? We want to be able to find an activity by typing in its name, an organization (or whichever associated model you are working with, and in my case, activity belongs to organization), a keyword, or even a zip code. So let’s write that code in.

The built-in Ruby array method .include? allows us to check if the user’s inputted search term can be found in any of those categories. The double pipes || represents “or” in Ruby. Notice how for zip code, we use the double equal signs instead because zip codes should be exact.

Step 3. safeguard against user input errors

Now moving on to our next goal, what if the user adds in a capital letter in the middle of the search term? Ruby has a handy function for that too, called downcase. We are going to implement it not only for search term, but also for all of the search categories for @activities so that they can match up.

And now, finally, our last feature before we move onto formatting it as a standalone search bar. How do we remove the whitespaces? Regex! Just insert this handy regex snippet gsub(/\s+/, “”) at the end of the search term to clean up white spaces that the user may have mistakenly typed into the search bar.

Hooray! We’ve created a dynamic search bar that allows you to narrow down results in so many different ways.

Step 4. format a standalone search bar

Now, as it is, in my HTML file, I have an @activities.each do block that iterates through all of the activities in my database. So right now, the search bar is appearing above our complete list of activities.

To create a standalone search bar, simply write a conditional in the activities controller such that if params[:search] does not exist, set @activities equal to an empty array.

Now, the user should only be able to see the search bar on the page. Results will only start populating after they submit in a search term.

Looking at it, I’d love to refactor the code a bit more to make it more DRY, but as it is, we just successfully implemented a really awesome search feature!


Massive thank you to

sylwiavargas image


for all of the incredible resources and pointers!

Top comments (2)

Collapse
 
aniketstiwari profile image
aniketstiwari • Edited

@activities = []
// You don't need an else condition. Also, Activity.all.select will be an expensive operation instead use where clause with joins
if params[:search]
search_term = params[:search].downcase.gsub(/\s+/, "")
@activities = Activity.joins(:organization, :zipcode).where("activity.name = :term OR activity.description = :term OR organization.name = :term OR organization.city = :term OR organization.state = :term OR zipcode.zip_num = :term ", term: search_term)

end

Collapse
 
wobsoriano profile image
Robert

Thanks!