Using Faker in a Rails Application

So you’ve just made a application using Ruby on Rails, and you want to have a lot of data on your site when you open it on your browser. But, typing it all out in a seed file is very tedious and would take you way too long. I personally recommend using Faker, which can randomly generate data depending on what fields you have to fill in.

Set-up

To set up Faker in your project, you need in install the Faker gem. If you have a Gemfile you can just add the line:

gem 'faker'

And then run bundle install in your terminal.

If you don’t have a Gemfile you can always just run the following line in your terminal:

gem install faker

And then once that’s set up all you have to do is require faker at the top of all of the files you want to use it in. If you’re just looking to make data for your rails app, you should just add this to the top of your seed file:

require 'faker'

Usage

You can use Faker anywhere in your project (As long as you require it at the top), but if you’re looking to add data to your rails database then you’re going to want to do this in your seed file.

Assuming you already have models set up, the first step would be to find out what Fakers you want to use. For example, if you’re making a application where you want a bunch of books, you would probably want to use the book Faker, which can generate strings like book titles, authors, genres, and publishers. You can find the whole list of all Fakers available on their Git Hub repository.

Some of the Fakers they have available.

They provide examples of the type of stuff each Faker will return if you click on the links provided, which is very helpful when you’re deciding what Fakers to use.

You create the fake data you want by running:

Faker::Book.title #=> "Catcher in the Rye"

And you can set this data to a variable, then you can call it when you create a new object for your database. EX:

title_1 = Faker::Book.title
Book.create(name: title_1)

If you want a few books with the same title you can always define ‘title_1' (like in the example above), and then create multiple books with that same variable as the book’s name. EX:

title_1 = Faker::Book.title
book_1 = Book.create(name: title_1)
book_2 = Book.create(name: title_1)
book_3 = Book.create(name: title_1)

But, I assume that you’d like to make some unique data in your database, you are trying to use Faker after all! In that case you could just define 3 different book titles and make the three books that way. EX:

title_1 = Faker::Book.title
title_2 = Faker::Book.title
title_3 = Faker::Book.title
book_1 = Book.create(name: title_1)
book_2 = Book.create(name: title_2)
book_3 = Book.create(name: title_3)

Now we’re getting places! However, as you may have noticed, this isn’t very DRY (Don’t repeat yourself). The shortest, most effective way to do this would be using a times do loop. EX:

3.times do
title_1 = Faker::Book.title
Book.create(name: title_1)
end

This code above will make 3 books with unique titles and put them in your database.

But what if you have more than just a title attribute for your book? You could always just define all of your variables in your times do loop. EX:

3.times do
title = Faker::Book.title
author = Faker::Book.author
pages = Faker::Number.between(100,1000)
year = Faker::Number.between(1918,2018)
  Book.create(name: title, author: author, pages: pages, year: year)                           
end

And this would work just fine, but it seems to be doing a little too much for one loop, so I’d like to split this up and make a method that sets up the hash that you’ll need to make a book. EX:

def prepare
title = Faker::Book.title
author = Faker::Book.author
pages = Faker::Number.between(100,1000)
year = Faker::Number.between(1918,2018)
{name: title, author: author, pages: pages, year: year}
end
3.times do 
Book.create(prepare)
end

This works because in the last line of my prepare method, I made the hash that the book needs, and a method in ruby always returns the result of it’s last line (unless you explicitly tell it to return something else).

Now imagine that you have a ‘has_many’ relationship in your database and want to create objects that are related to each other. You would want to do something similar to the code above but you need to pass in the already created object so that your other method has access to it. EX:

def prepare
title = Faker::Book.title
author = Faker::Book.author
pages = Faker::Number.between(100,1000)
year = Faker::Number.between(1918,2018)
{name: title, author: author, pages: pages, year: year}
end
def review_book(book_instance)
title = Faker::Hipster.sentence(4)
body = Faker::Hipster.paragraph(2)
rating = Faker::Number.between(1,5)
new_review = book_instance.reviews.create(title: title, body: body, rating: rating)
end
3.times do 
book = Book.create(prepare)
  5.times do 
review_book(book)
end
end

This would create 3 different books, all with 5 unique reviews, and in such little code! Imagine how long it would take you to type out all of that information to make everything look different in your database.

You can do a lot of really cool things with Faker like creating authors who have many books, books who have many authors and reviews, and users who have many reviews. And all of that with random information that you don’t have to type in. I’m using this as a example because this is actually a project that I created with all of that data being made with Faker. And because I wanted to make a bunch of the data as random as possible, I did some extra trickery, which made my seed file 100 lines of code. But considering all of that data I would have had to create if I hadn’t used Faker, it saved me a lot of time. Plus, it made me laugh every time I looked at my site, as I used the Hipster Faker for my reviews and it made some really hilarious reviews. EX:

"Migas fingerstache pbr&b tofu. Polaroid distillery typewriter echo tofu actually. Slow-carb fanny pack pickled direct trade scenester mlkshk plaid. Banjo venmo chambray cold-pressed typewriter. Fap skateboard intelligentsia."

Cool Extra Features

To insure random data, you can use the unique method. EX:

Faker::Name.unique.name

This will always return a unique name. Until it runs out of all of the names it has for you to use, then aFaker::UniqueGenerator::RetryLimitExceeded exception may be raised.

You could also use the random method which sets a seed for the data in the way that it’s provided. So if you want a specific list of information you can insure that by using this method. EX:

Faker::Config.random = Random.new(42)
Faker::Company.bs #=> "seize collaborative mindshare"
Faker::Company.bs #=> "engage strategic platforms"
Faker::Config.random = Random.new(42)
Faker::Company.bs #=> "seize collaborative mindshare"
Faker::Company.bs #=> "engage strategic platforms"