5

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: "example@railstutorial.org",
             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"

Hanna
  • 539
  • 2
  • 9
  • 24
  • I dont see a problem with your seeds file. Are you sure the db dropped properly. Maybe go inside rails c and check if there is anytging persisted. Or try catching the exception and identifying which record is causing the problem. –  May 01 '15 at 12:25

4 Answers4

5

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: "example@railstutorial.org" )
  # 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!

Community
  • 1
  • 1
ConnorCMcKee
  • 1,625
  • 1
  • 11
  • 23
  • Thanks for your answer...I run the commands you mentioned without rake db:prepare but still the error remains...I'm so confused, really don't know what to do! – Hanna May 01 '15 at 13:45
  • Just for clarity, you were running four commands at the beginning ( `rake db:reset, rake db:migrate, rake db:test:prepare, rake db:prepare` ) and getting an error on the last one, correct? If so, simply don't run the last one. The error you are getting is because the last command is redundant. – ConnorCMcKee May 01 '15 at 14:15
  • No I didn't run 'rake db:prepare' – Hanna May 01 '15 at 17:00
  • Then what exactly are you running when the error manifests itself now? `rake db:prepare, rake db:reset, rake db:seed, and bundle exec rake db:Seed` are all running your seeds. Using more than one will always give you this error. – ConnorCMcKee May 01 '15 at 17:24
  • Ok... What should I do now? The error appeared when I ran `bundle exec rake db:Seed`(I hadn't run `rake db:prepare, rake db:reset, rake db:seed`) ... I searched and tested every answers here. I think it appears because I have example-1@railstutorial.org and example-100@railstutorial.org in database. – Hanna May 01 '15 at 18:29
  • Yes, you are correct, the error is occuring because those two are in the database already. So essentially what you want to do now is get rid of those entries that are causing problems, and recreate the database, seeds and all. All you really need to do is run `rake db:reset`. You've been experiencing something of a non-problem here; the error is telling you you've already done what you're trying to do, and it's right, this will simply prove it by rebuilding and populating the database there (if you get no errors, and the records are in your db, then it worked). – ConnorCMcKee May 01 '15 at 18:41
  • Sorry I asked again, so there won't be any problem if I leave it that way I don't change anything? This tutorial confused me. – Hanna May 01 '15 at 18:53
  • 1
    Ah, I understand. You are correct, there's no problem. All Mr. Hartl wants you to do in that passage is put the seeds into your database, and you have successfully done so. – ConnorCMcKee May 01 '15 at 18:59
  • your unless statement can be simplified from `unless User.find_by( email: "example@railstutorial.org" )` to `unless User.exists?`, which will return `true` if there is at least 1 User record, or `false` if not. this is an ActiveRecord feature btw. – clairity Feb 21 '17 at 21:57
1

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.

Community
  • 1
  • 1
Drenmi
  • 8,492
  • 4
  • 42
  • 51
-1

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: "example@railstutorial.org",
         password:              "foobar",
         password_confirmation: "foobar",
         admin:     true,
         activated: true,
         activated_at: Time.zone.now)
user.errors
user.save if user.valid
Abdul Baig
  • 3,683
  • 3
  • 21
  • 48
  • The same thing 'Validation failed: Email has already been taken' – Hanna May 01 '15 at 12:30
  • go to console and see output of `User.all.pluck(:email).sort` and see for email id's if exist between example-1@railstutorial.org.....example-100@railstutorial.org – Abdul Baig May 01 '15 at 12:31
  • One of them is "example@railstutorial.org" which was defined at first and others are between example-1@railstutorial.org and example-100@railstutorial.org – Hanna May 01 '15 at 12:35
  • and you have validation on user email. so `User.delete_all` then `rake db:seed` or `rake db:drop db:create db:migrate` then `rake db:seed` should work – Abdul Baig May 01 '15 at 12:39
  • I deleted all users as you said and ran rake db:drop rake db:create , rake db:migrate , rake db:seed...but after that when I run bundle exec rake db:seed I see this again:(and in User.all.pluck(:email).sort I can see all those emails again!) rake aborted! ActiveRecord::RecordInvalid: Validation failed: Email has already been taken – Hanna May 01 '15 at 13:02
-1

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/

Mike
  • 31
  • 6