In Progress
Unit 1, Lesson 21
In Progress

Faker

Populating a prototype with sample data, generating test data sets, anonymizing production data dumps… there are a lot of reasons to need random-but-realistic fake information. In this episode, you’ll learn about a handy gem to automate all of your fake data needs.

Video transcript & code

Today's episode is about one of those supporting tools that has shown up in the background of a lot of episodes before. But I recently realized that I hadn't dedicated a full episode to it.

Imagine we're building a social web application, and we want to demo it to the client as it will appear in production. Which means that we need to fill it with a bunch of realistic-looking example user accounts.

Of course, as soon as we start trying to think about example user names and email addresses, etc., our minds go blank. Thankfully, generating realistic example data is not something that we need to do manually. There is a Rubygem for that! And it's called faker.

After installing the faker Rubygem, we require it in our code.

Using classes in the Faker library, we can generate random names.

There are variations on this; for instance, we can ask for a name that includes a middle name, just a first name, just a last name, or even a title.

require "faker"
Faker::Name.name                # => "Ewald Romaguera"
Faker::Name.name_with_middle    # => "Berneice Elise Kris III"
Faker::Name.first_name          # => "Milo"
Faker::Name.last_name           # => "Herman"
Faker::Name.title               # => "Lead Assurance Assistant"

We can generate random email addresses too.

The addresses faker generates by default might turn out to be real-world addresses by accident. To get "safe" addresses based on one of the official example domains, we can ask for a safe_email instead.

If we want our email addresses to be consistent with user names, we can specify a name.

The same Internet subclass can also generate numerous other useful example values, such as user names , passwords, , and random URLs . Check out the Faker documentation to see many more options.

require "faker"
Faker::Internet.email           # => "talia.lebsack@rutherford.com"
Faker::Internet.safe_email                # => "nelson.cain@example.net"
Faker::Internet.safe_email("Avdi Grimm")
# => "grimm.avdi@example.net"

Faker::Internet.user_name       # => "daphnee"
Faker::Internet.password        # => "E0UpYqD4O6HiKu"

Faker::Internet.url
# => "http://westryan.co/zander_beer"

Should our example users have an associated snail-mail address? If so, it's not a problem, using the Address subclass.

require "faker"
Faker::Address.street_address
# => "912 Karlie Haven"
Faker::Address.city
# => "East Earnesttown"
Faker::Address.state
# => "Montana"
Faker::Address.postcode
# => "52092"
Faker::Address.country
# => "Fiji"

Maybe we want to include marital status in our user profiles? We can do that too, using the Demographic class.

require "faker"
Faker::Demographic.marital_status
# => "Divorced"

Should the user profiles also have employer information? The Employer class may come in handy.

require "faker"

Faker::Company.name
# => "Cruickshank-Gutkowski"

While we're looking at it, in a pinch this class can also be used to generate corporate vision statements!

require "faker"

Faker::Company.bs
# => "orchestrate integrated applications"

We can even generate working avatar image URLs, using the Avatar class.

require "faker"

Faker::Avatar.image
# => "https://robohash.org/repellateaquedolorem.png?size=300x300&set=set1"

Do we need to generate different join-up dates for the various users? The Time class can help. For instance, we can ask for a date sometime in the last year.

require "faker"

Faker::Time.backward(365)
# => 2017-01-24 02:04:30 -0500

What about filler text? We might want to populate a user's status updates with placeholder verbiage. In that case, we can use the Lorem class to generate words, sentences, and paragraphs from the classic "lorem ipsum" text.

require "faker"

Faker::Lorem.words(3)
# => ["deserunt", "sed", "nostrum"]
Faker::Lorem.sentence
# => "Et perferendis dolores aspernatur dolore."
Faker::Lorem.paragraph(3)
# => "Praesentium velit velit eligendi nihil vel. Non omnis incidunt eaque quia architecto dolore qui. Omnis dolorum nulla perferendis excepturi ut minima. Sit accusantium qui."

So far, we've been looking at pretty simple generated sample values. But faker also has some facilities for simulating the data formats of certain popular web services. For instance, if our application enables users to link their Twitter account, we might want to use faker's Twitter class to generate a sample Twitter user record. The data generates simulates the format Twitter returns from their JSON API.

require "faker"

Faker::Twitter.user
# => {:id=>4905339896933738579,
#     :id_str=>"4905339896933738579",
#     :name=>"Mr. Laverne Kozey",
#     :screen_name=>"sylvester_hamill",
#     :location=>"Lake Carlotta, MI, IT",
#     :description=>"Et itaque commodi harum quibusdam saepe ullam autem.",
#     :url=>"http://example.com/kaden",
#     :entities=>nil,
#     :protected=>false,
#     :followers_count=>457546,
#     :friends_count=>33080,
#     :listed_count=>338,
#     :created_at=>"Thu May 04 00:00:00 +0000 2017",
#     :favourites_count=>93927,
#     :utc_offset=>41419,
#     :time_zone=>"Europe/Athens",
#     :geo_enabled=>true,
#     :verified=>false,
#     :statuses_count=>358,
#     :lang=>"MR",
#     :contributors_enabled=>false,
#     :is_translator=>false,
#     :is_translation_enabled=>false,
#     :profile_background_color=>"#1d686c",
#     :profile_background_image_url=>"http://lorempixel.com/600/400",
#     :profile_background_image_url_https=>"http://lorempixel.com/600/400",
#     :profile_background_tile=>false,
#     :profile_image_url=>
#      "http://robohash.org/4905339896933738579.png?size=48x48&set=set1",
#     :profile_image_url_https=>
#      "https://robohash.org/4905339896933738579.png?size=48x48&set=set1",
#     :profile_banner_url=>"http://lorempixel.com/1500/500",
#     :profile_link_color=>"#9b786f",
#     :profile_sidebar_border_color=>"#c38e95",
#     :profile_sidebar_fill_color=>"#035078",
#     :profile_text_color=>"#916e8d",
#     :profile_use_background_image=>false,
#     :default_profile=>false,
#     :default_profile_image=>false,
#     :following=>false,
#     :follow_request_sent=>false,
#     :notifications=>false,
#     :status=>
#      {:created_at=>"Tue Mar 05 00:00:00 +0000 2013",
#       :id=>596800969320930930,
#       :id_str=>"596800969320930930",
#       :text=>"Omnis necessitatibus vel ea iure et neque delectus.",
#       :truncated=>false,
#       :entities=>nil,
#       :source=>
#        "<a href=\"http://example.com/ulises_littel\" rel=\"nofollow\">Krajcik, Schaefer and Hermiston</a>",
#       :in_reply_to_status_id=>nil,
#       :nil=>nil,
#       :in_reply_to_user_id=>nil,
#       :in_reply_to_user_id_str=>nil,
#       :in_reply_to_screen_name=>nil,
#       :geo=>nil,
#       :coordinates=>nil,
#       :place=>nil,
#       :contributors=>nil,
#       :retweeted_status=>nil,
#       :is_quote_status=>false,
#       :retweet_count=>5563,
#       :favorite_count=>687,
#       :favorited=>false,
#       :retweeted=>false,
#       :possibly_sensitive=>false,
#       :lang=>"AI"}}

faker also provides a number of generators which are just plain fun. It can pick a random beer variety, recite Chuck Norris facts, and toss out Star Wars characters.

require "faker"

Faker::Beer.name
# => "St. Bernardus Abt 12"

Faker::ChuckNorris.fact
# => "Chuck Norris can read all encrypted data, because nothing can hide from Chuck Norris."

Faker::StarWars.character
# => "Boba Fett"

Check out the gem's documentation for more, although be aware that some of the generators which are documented on the master branch might not have made it into the gem yet.

In some cases, we might want to guarantee that we don't have any duplicate sample values. In that case we can ask faker to generate only unique values. Internally it will keep a record of what has been generated so far.

require "faker"

Faker::Name.unique.name
# => "Gordon Lemke DDS"

Faker::Name.unique.name
# => "Miss Rita Renner"

Faker::Name.unique.name
# => "Emiliano Kris"

faker is great for generating example data to populate an application database. But another way I like to use it is to quickly create realistic example data files. For instance, in a recent episode I needed a listing of names and email addresses in comma-separated values (CSV) format. Here's the code I used to create it:

After requiring the faker and csv libraries, it opens a CSV file for writing in binary mode. It iterates 10 times, each time appending a new line of faker-generated data to the CSV file.

require "faker"
require "csv"

CSV.open("list.csv", "wb") do |csv|
  10.times do
    csv << [Faker::Name.name, Faker::Internet.safe_email]
  end
end

We can open the resulting file and see the generated data.

Jillian Mraz,domenica@example.org
Ludwig Ernser,luisa_towne@example.com
Eden Hills,pinkie@example.org
...

As you can see, the faker gem is a wonderfully convenient tool for generating random data. The next time you need some real-looking sample data to populate a demo, forget about Jane Doe and John Smith, and and ask faker for some values instead. Happy hacking!

Responses