Removing User_ID from url params with Devise and FriendlyId gem

We have all our user profiles rendering through a handlebars template but as the attributes associated to the user grows, so does the loading time.

The only reason we have them loading through a handlebars template as opposed to a ruby template, is that the user_id is in the URL for devise/show.

Here is a quick guide to replicate how I solved that:



gem 'friendly_id', '~> 5.1.0'


rails generate friendly_id


I already have Devise set up for user authentication, so next I ran

rails g migration AddSlugToUser slug:string:uniq

Which produced this migration file:

class AddSlugToUser < ActiveRecord::Migration[5.0]
 def change
   add_column :users, :slug, :string
   add_index :users, :slug, unique: true


Mmmmkay – let’s migrate those goodies

rake db:migrate



I want the URL to use the first_name of the user. Many members might have the same first name, so I’m going to give the function a few options. The first option is to use just the first name. If that is taken, append a random number 1-10. If that is taken, append a random number 1-100, and then 1-1000.


class User < ApplicationRecord

  extend FriendlyId
  friendly_id :slug_candidates, use: :slugged

  def slug_candidates
      [:first_name, rand(1..10)],
      [:first_name, rand(1..100)],
      [:first_name, rand(1..1000)]



Now I ran in the console:


And I can see each user now has an attribute called slug, and it is their first_name, plus a unique number (or just first_name for the early birds!)


Adapt current setup

Currently, I have a profile controller, where each user can view their own profile


 get 'profile/:id', to: 'profile#view', as: 'view'

So, for the signed in user to view their profile, I changed the link to:

link_to main_app.view_path(current_user.slug)


Now, to render another user’s profile, running through an array of User records:

link_to image_tag(user.avatar.url(:medium)), main_app.view_path(user.slug)





Since I’m not requiring users to have a unique first_name, this will occasionally end up in a REALLY ugly url, such as:


because there are sooo many Walshs in the world.


The next step is to put the ability for a user to chose their own unique URL identifier, and save it in their settings. This will cut down on the chance that a unique name+number will be taken, when creating new users. I might write another blog post about this in the future, but for now it’s pretty straight forward in Friendly_id’s documentation


One interesting ‘gotcha’ I discovered later:


Started GET "/profile/queue" for ::1 at 2017-04-13 11:05:57 -0500

  Processing by ProfileController#view as HTML

  Parameters: {"id"=>"queue"}

Completed 401 Unauthorized in 1ms (ActiveRecord: 0.0ms)


Here, there was a route to a page called profile/queue. But now that the view is not profile/:id in a numeric, ActiveRecord id sense, it is looking for a slug called ‘queue’


Simple fix:

get 'profile/queue', to: 'profile#queue', as: 'queue'


get 'queue', to: 'profile#queue', as: 'queue'



PS. My roommate has a goldfish name Friendly, which is why the image for this post is a goldfish 🙂



Lexody wins at SXSW!

Lexody was invited to pitch at SXSW’s Pitch Accelerator.

After 2 rounds, and 30 incredibly qualified companies, Lexody was ultimately crowned the Best One-Minute Pitch!

No, Keith McKellar and I, did not plan coordinating outfits that day… but must have know we would be taking pictures holding a giant check.

Watch the winning pitch:

Thank you for all your support! We are both really excited about the future, and know this is the first of many accomplishments for Lexody!


-Walsh Costigan, Founder

Make a Rails5 API that spits out JSON

This post is for me. Specifically to work with another app, which takes an api, and spits out a random question from another API.

create new rails app

rails new app_name --api


Create a table

rails g scaffold table_name attribute:type


We want a random question to be returned. In the Questions Controller, index method:

@questions = Question.order("RANDOM()").limit(1)


In order to allow the api to be accessed by a different app/url, add in application.rb:


 'Access-Control-Allow-Origin' => '*',
 'Access-Control-Request-Method' => '*'


Because I’m deploying with Heroku, which uses PostgresSQL (Not sqlite) in Gemfile, remove

gem 'sqlite3'

and replace with

group :development, :test do
 gem 'sqlite3'
 gem 'rspec-rails', '3.0.1'

group :production do
 gem 'pg'
 gem 'rails_12factor'


Create new git repo on github, and follow directions on pushing

Deploy to Heroku

heroku create, push, rake db, seed, open, et voila!