Crawl Vote: Helping groups on the move pick a next spot
Tags: pushercontest, rails, vue
Published: 2018-05-24 15:37:16

---
title: Crawl Vote: Helping groups on the move pick a next spot
published: true
description: An app submitted to the first-ever DEV Community contest. 
tags: pushercontest, rails, vue
cover_image: https://thepracticaldev.s3.amazonaws.com/i/042wh61rlvlh7lam6av3.png
---

# What I built

Crawl Vote helps groups on the move pick a next spot. Whether they’re looking for poutine in Montreal or tacos in Tijuana, Crawl Vote will return some suggestions for everyone to vote on together.

## Demo link

https://crawlvote.com

## Link to code

{% github nholden/crawl_vote %}

# How I built it

Crawl Vote uses [Ruby on Rails](https://rubyonrails.org/) on the back end [Vue.js](https://vuejs.org/) on the front end. I used [Webpacker](https://github.com/rails/webpacker), which comes with a [Vue integration](https://github.com/rails/webpacker#vue), to compile and bundle my JavaScript, CSS, and images. I used [Tailwind](https://tailwindcss.com/) to quickly prototype my design without writing any CSS.

I used [Pusher Channels](https://pusher.com/channels) in a couple ways. When a user first submits where they’re going and what they’re looking for, Crawl Vote creates a new “crawl”, gives it a unique name, and subscribes the user to a Pusher channel with that name. Then, the application kicks off a [Sidekiq](https://sidekiq.org/) job to query [Yelp’s Fusion API](https://www.yelp.com/fusion) in the background. Once the job has fetched relevant businesses and persisted them to the [PostgreSQL](https://www.postgresql.org/) database, it triggers an event to the Pusher channel. When the user’s browser receives the event, a Vue component uses the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) to make a request to grab all of the relevant data and display it on the screen.

Once the user has successfully created a crawl and invited some friends, Pusher Channels allow everyone to see the voting in real time without refreshing their browsers. When a user clicks the vote button next to a spot, it makes a request to the application that persists the vote and triggers an event to the Pusher channel. When all the users’ browsers receive the event, the Vue component makes another request to refresh the data on the screen.

![Crawl Vote demo](https://thepracticaldev.s3.amazonaws.com/i/x0f896noabygq0f0xhkz.gif)

I had never used Vue’s [List Move Transitions](https://vuejs.org/v2/guide/transitions.html#List-Move-Transitions) before, but I was really impressed how, with very little CSS, Vue added silky smooth animations as spots moved up and down in the rankings. Magic! ✨

To identify users, Crawl Vote assigns each person a UUID and stores it in the user’s session. When a user first visits a crawl or refreshes the page, the applications identifies the user directly from the session and renders the data server side. When the user’s browser receives a Pusher event letting it know that it’s time to fetch more data, the UUID is sent along as a token in the [authorization request header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization).

Crawl Vote is continuously deployed to [Heroku](https://www.heroku.com/) by [Travis CI](https://travis-ci.com/) and is served by [Cloudflare](https://www.cloudflare.com/). I’m using [Rollbar](https://rollbar.com/) for exception tracking and [Papertrail](https://papertrailapp.com/) for logging. The only thing I paid for was the domain name, which came from [Namecheap](https://www.namecheap.com/).

# What’s next

I’m happy with how things turned out for this MVP, but I have a whole bunch of things I’d love to try with more time. I’d like to increase test coverage, including at least one or two [Rails system tests](http://guides.rubyonrails.org/testing.html#implementing-a-system-test) that click through my Vue components using [Headless Chrome](https://developers.google.com/web/updates/2017/04/headless-chrome).

I’d also like to continue improving the UX/UI, including adding autocomplete to the form fields. The categories that Yelp’s [autocomplete endpoint](https://www.yelp.com/developers/documentation/v3/autocomplete) returns look like they could be useful for the “Find” field, and I’ve been happy working with Google’s [Place Autocomplete](https://developers.google.com/places/web-service/autocomplete) in the past. The design overall could use a little sprucing up, and I think some thoughtful use of color could help the look and feel better reflect the spirit of the app.

Finally, it would be great to do some more tweaking with the parameters Crawl Vote sends along to Yelp’s API. There are [a lot of options](https://www.yelp.com/developers/documentation/v3/business_search), and I’m not sure I’d want to expose too many to the user since the complexity could turn people away, but I’d love to do some optimizing to make sure Crawl Vote returns a great selection of spots for every query.