Seeding Users with Photos in Rails
Tags: rails, ruby, tutorial
Published: 2022-12-07 01:27:13

When starting a new project, adding seeds gives life to your application. It gives you some initial data to play around with and adding users is normally an integral part of it. They tricky part is that we want it to feel real without actually using people's photos or information.

## Using Faker
I'm going to assume that we're using Devise for our User model. That means we'll most likely be logging in with an email. Let's use the gem [Faker](https://github.com/faker-ruby/faker), but you have to be careful with this one. Some of their emails are real. The last thing you want to do is accidentally email all of those `@gmail.com` addresses you seeded into your database.

If you use `Faker::Internet.safe_email`, then it'll guarantee you're using an email address that can't receive messages (ie: `margert_huel@example.net`). To counteract the `@example.com`, I like to use the real emails of the other members in my team. This allows them to always know an email they can sign in with. Otherwise every time you run your seeds, you'll have to open the Rails console and find a new users's email.

Don't forget to add the gem into your `Gemfile`.

```
gem 'faker', :git => 'https://github.com/faker-ruby/faker.git', :branch => 'main'
```
Once you've added the new gem, you need to make sure it's installed. From your Terminal:

```
bundle install
```

## Attaching a Photo
We need to go inside our User model first (`user.rb`) and attach a photo

```
# ...
has_one_attached :photo
# ...
```
Take this as an example:

```
require "open-uri" # at the top

article = Article.new(title: 'NES', body: "A great console")
file = URI.open('https://giantbomb1.cbsistatic.com/uploads/original/9/99864/2419866-nes_console_set.png')
article.photo.attach(io: file, filename: 'nes.png', content_type: 'image/png')

```
But, that's only one photo on one instance of an `article`. How can we generate a unique photo for each user that we seed in the database? We can user [this-person-does-not-exist.com](https://this-person-does-not-exist.com/en). This website uses AI to generate photos of fake people.

So let's attach those AI photos to our users:

```
require 'open-uri'
require 'nokogiri'

50.times do
  user = User.create!(
  email: Faker::Internet.safe_email,
  password: '123123', # needs to be 6 digits,
  # add any additional attributes you have on your model
)
  # gender options: 'all' or 'male' or 'female'
  gender = 'male'
  # age options: 'all' or '12-18' or '19-25' or '26-35' or '35-50' or '50+'
  age = '19-25'
  # ethnicity options: 'all' or 'asian' or 'white' or 'black' or 'indian' or 'middle_eastern' or 'latino_hispanic'
  ethnicity = 'all'

  url = "https://this-person-does-not-exist.com/new?gender=#{gender}&age=#{age}&etnic=#{ethnicity}"
  json = URI.open(url).string
  src = JSON.parse(json)['src']
  photo_url = "https://this-person-does-not-exist.com#{src}"
  file = URI.open(photo_url)
  user.photo.attach(io: file, filename: 'user.png', content_type: 'image/png')
end
```

## Make Sure They Attached
Go to your Terminal and open up a rails c

```
rails c
```
Pull up the last user and make sure a photo is attached

```
User.last.photo.attached? # if true, success!
```