Hanna
Hanna

Reputation: 539

Validation failed on rake db:seed

I'm doing chapter 12 of hartle's tutorial. When I ran bundle exec rake db:seed I got this error:

ActiveRecord::RecordInvalid: Validation failed: Email has already been taken

I try running

rake db:reset
rake db:migrate
rake db:test:prepare

And at last

rake db:populate 

but they didn't solve the problem. When I run rake db:populate it gives:

Don't know how to build task 'db:populate'

This is my seeds.rb file:

    # Users
User.create!(name:  "Example User",
             email: "[email protected]",
             password:              "foobar",
             password_confirmation: "foobar",
             admin:     true,
             activated: true,
             activated_at: Time.zone.now)

99.times do |n|
  name  = Faker::Name.name
  email = "example-#{n+1}@railstutorial.org"
  password = "password"
  User.create!(name: name,
              email: email,
              password:              password,
              password_confirmation: password,
              activated: true,
              activated_at: Time.zone.now)
end

# Microposts
users = User.order(:created_at).take(6)
50.times do
  content = Faker::Lorem.sentence(5)
  users.each { |user| user.microposts.create!(content: content) }
end

# Following relationships
users = User.all
user  = users.first
following = users[2..50]
followers = users[3..40]
following.each { |followed| user.follow(followed) }
followers.each { |follower| follower.follow(user) }

I guess maybe the problem is with this line email = "example-#{n+1}@railstutorial.org"

Upvotes: 5

Views: 6402

Answers (4)

ConnorCMcKee
ConnorCMcKee

Reputation: 1645

Your problem is that rake db:reset not only drops and recreates the database, but it also migrates and seeds it as well. So essentially what's happening is this:

rake db:drop
rake db:create
rake db:schema:load # (think of this as running all the migrations you've run before)
rake db:seed # (creates your 100 database users)

and then you run:

rake db:migrate # (likely unnecessary, but it causes no harm)
rake db:test:prepare # (prepares the test database)
rake db:prepare # (runs the seeds AGAIN and causes your errors)

Obviously, from this if you just stop running the rake db:prepare command your problem will go away. However, to avoid these things in the future, I strongly recommend putting a little bit of logic in your seed file. It's just Ruby, so you could wrap the User creates in an unless statement, such as:

unless User.find_by( email: "[email protected]" )
  # create all 100 users
end

This will prove to be especially valuable if you have a site on production that still uses seed data (such as a SiteSetting table); you need to make sure the data makes its way into your production database, but you'll create duplicate records (or errors) running the seed again without dropping.

As an additional reference for the answer to your question, see the selected answer to this one.

I hope this provides all the information you need!

Upvotes: 5

Drenmi
Drenmi

Reputation: 8777

I'm doing chapter 12 of hartle's tutorial. When I ran bundle exec rake db:seed I got this error:

ActiveRecord::RecordInvalid: Validation failed: Email has already been taken

When you run rake db:reset, it will seed the database for you. When you then run rake db:seed, an exception will be thrown, because you are using create! in your seeds.rb file. Unlike create, create! raises an exception when the validations fail.

You can check this by running rake db:reset, and then using rails console to check your database entries.

There are a couple things you could do to prevent this, but why would you, when your data is already there?

When I run rake db:populate it gives:

Don't know how to build task 'db:populate'

Unless you define it yourself, there is no rake task named db:populate.

Upvotes: 1

Mike
Mike

Reputation: 29

Do you have both faker and populator installed in your Gemfile? That is most likely apart of the issue. Make sure you have run:

gem install populator #From the command line

and include it in your Gemfile:

gem 'populator'

Here is a link to the Git repo https://github.com/ryanb/populator/tree/master

Great article here also: http://sudharti.github.io/articles/using-faker-and-populator-rails/

Upvotes: -1

Abdul Baig
Abdul Baig

Reputation: 3721

try using:

if the case is already existing email it will solve it.

email = "example-#{rand(100000)}@railstutorial.org"

and you can also see errors:

user = User.new(name:  "Example User",
         email: "[email protected]",
         password:              "foobar",
         password_confirmation: "foobar",
         admin:     true,
         activated: true,
         activated_at: Time.zone.now)
user.errors
user.save if user.valid

Upvotes: -1

Related Questions