Question

I want to populate the database with a number of stores and users, that each user corresponds to one store. The issue with the code below is that I get the error Validation failed: Email has already been taken.

namespace :db do
  desc "Fill database with sample data"
  task populate: :environment do
    make_stores
    make_users
  end
end

def make_stores
  50.times do 
    name = Faker::Company.name
    manager = Faker::Name.name
    address = Faker::Address.street_name
    Store.create!(name: name,
                  manager: manager,
                  address: address)
  end
end

def make_users
  stores = Store.all(limit: 8)

  99.times do |n|
    first_name  = Faker::Name.first_name
    last_name = Faker::Name.last_name
    email = "example-#{n+1}@example.org" 
    password  = "password"
    stores.each { |store| store.users.create!(first_name: first_name,
                  last_name: last_name,
                 email:    email,
                 password: password,
                 password_confirmation: password) }
  end
end
Was it helpful?

Solution

The problem is that you're setting the email variable before calling stores.each, so all 8 stores will get a user with the same email.

Do something like this instead:

def make_users
  stores = Store.all(limit: 8)

  99.times do |n|
    password  = "password"
    stores.each do |store|
      first_name  = Faker::Name.first_name
      last_name = Faker::Name.last_name
      email = "#{store.name.parameterize}-#{n+1}@example.org" 
      store.users.create!(first_name: first_name,
                  last_name: last_name,
                  email:    email,
                  password: password,
                  password_confirmation: password)
    end
  end
end

Now the first 8 users will have an email like (some-store-name)-1@example.org, next 8 will have (some-store-name)-2@example.org and so on.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top