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"
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!
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.
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
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/
Related
I use active_admin in local environment and it works fine.
I can login as adminuser after executing "rake db:seed".
(here is my seed.rb file)
AdminUser.create!(email: '1#1', password: '123456', password_confirmation: '123456') if Rails.env.development?
However in production environment, I can't access to active_admin page as admin_user.
I already tried "rake db:seed RAILS_ENV=production" but it's not working.
(here is my seed.rb file in production mode)
AdminUser.create!(email: '1#1', password: '123456', password_confirmation: '123456') if Rails.env.production?
(here is my logs)
Anyone plz help thanks!
I am running through Hartl's Rails tutorial, but when I try to seed Microposts I am getting the error: "ActiveRecord::RecordInvalid: Validation failed: Email has already been taken"
I did db:migrate:reset followed by db:seed which throws up the error. Is there something wrong with what I am trying to seed?
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
users = User.order(:created_at).take(6)
50.times do
content = Faker::Lorem.sentence(word_count: 5)
users.each { |user| user.microposts.create!(content: content) }
end
You have probably already created some records in the database, which invokes validation. To check this, run the console rails c and then type User.first.
If you have some records run rake db:reset to reset database.
If you want to be able to run the seed multiple times, write
User.find_or_create_by(email: email) do |u|
u.name: name,
u.password: password,
u.password_confirmation: password,
u.activated: true,
u.activated_at: Time.zone.now
end
instead your code.
Instead of create! user create so if the email address is already taken, the record would not be created and the script gracefully continues, and you won't get an exception.
I'm not sure what exactly happened but I went ahead and reset my migrations once more and when I reseeded it worked. So if anyone else has this problem in the future, just clear the database again and try again.
In my case I had a syntax error when calling Rake :: .....
It worked for me to update the gem with gem 'faker', '~> 2.15', '> = 2.15.1'
Then rails db: migrate: reset and rails db: seed.
Is it possible to run one or two blocks within my seeds.rb code like you can with tests and gemfiles?
For example, if I had the following code in my seeds.rb file, could I just seed the Employee model?
20.times do
Employee.create!(name: "Bob",
email: Faker::Internet.email)
end
20.times do
User.create!(name: "Hank",
password: "foobar")
end
If this were my entire seeds.rb file, running rake db:seed would create 20 additional users when I only want to add more employees.
You can pass an option while running rake db:seed like following:
rake db:seed users=yes
And, then in your code, you can access it through the following way:
20.times do
Employee.create!(name: "Bob",
email: Faker::Internet.email)
end
if ENV["users"]
20.times do
User.create!(name: "Hank",
password: "foobar")
end
end
I've used the following setup for a couple of years now to help my sanity.
In db/seeds I have the following files:
001_providers.rb
005_api_users.rb
007_mailing_lists.rb
010_countries.rb
011_us_states.rb
012_canadian_provinces.rb
013_mexican_states.rb
100_world_cities.rb
101_us_zipcodes.rb
My db/seeds.rb file looks like this:
if ENV['VERSION'].present?
seed_files = Dir[File.join(File.dirname(__FILE__), 'seeds', "*#{ENV['VERSION']}*.rb")]
raise "No seed files found matching '#{ENV['VERSION']}'" if seed_files.empty?
else
seed_files = Dir[File.join(File.dirname(__FILE__), 'seeds', '*.rb')]
end
seed_files.sort_by{|f| File.basename(f).to_i}.each do |file|
require File.join(File.dirname(__FILE__), 'seeds', File.basename(file, File.extname(file)))
end
Just a bit of ruby code to let me run one or more seed files. I can now do things like this:
# run them all
bin/rake db:seed
# run just 001_providers.rb
bin/rake db:seed VERSION=001
# run all seeds for the USA (probably dangerous, but if you name your seeds right, could be useful).
bin/rake db:seed VERSION=us
One thing that is very important is that your seed files should be able to be run over and over and over and end up with a consistent state. If you run your seeds over and over you'll end up with many more users than just 20.
For example, my providers one has a main loop like this:
# providers is a hash of attributes...
providers.each_with_index do |(code, attrs), i|
p = Provider.find_by(code: code) || Provider.new(code: code) p.update!(attrs)
end
This way regardless of when I run it, I always get back exactly the providers I defined in my hash.
I'm currently going through the RoR guides, and i'm stuck at...
"Adding following/follower relationships to the sample data."
Here's the code that is suppose to work: sample_app/lib/task/sample_data.rake
namespace :db do
desc "Fill database with sample data"
task populate: :environment do
make_users
make_microposts
make_relationships
end
end
def make_users
admin = User.create!(name: "Example User2",
email: "example2#railstutorial.org",
password: "foobar",
password_confirmation: "foobar")
admin.toggle!(:admin)
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)
end
end
def make_microposts
users = User.all(limit: 6)
50.times do
content = Faker::Lorem.sentence(5)
users.each { |user| user.microposts.create!(content: content) }
end
end
def make_relationships
users = User.all
user = users.first
followed_users = users[2..50]
followers = users[3..40]
followed_users.each { |followed| user.follow!(followed) }
followers.each { |follower| follower.follow!(user) }
end
when i do rake db:reset my database reset with no problems.
when i do rake db:populate an error occurred stating this:
rake aborted!
Validation failed: Follower can't be blank`
so i checked my database, and all tables were populated except for "relationships" table.. any thoughts or suggestions? I'm pretty sure there's a problem with the code, def making_relationships, to be exact. hope anyone has a solution to this..
-Marc
Since you're calling .create! on models like User and Micropost (user.microposts), it is one of them throwing the error mentioned.
Please, post the code for these models to enable us answer more specifically.
You can still debug the problem by yourself though. Just hit rails c in the projects root directory, and try to create instances with the very same attributes you're trying in rake task:
$ rails c
$ user = User.create!(name: name,
email: email,
password: password,
password_confirmation: password)
$ micropost = user.microposts.create!(content: "Hello, cruel world!")
# by this step you should already see some errors raised; if that's not sufficient,
# call the following methods to figure out what model suffers the validation error
user.errors.full_messages
micropost.errors.full_messages
Anyway, it's the validation that's not satisfied. Double check you're passing all required attributes passed when creating a model with a shebang create!. Specifically check which model requires presence of Follower (whatever that is).
I've been using the Authlogic rails plugin. Really all I am using it for is to have one admin user who can edit the site. It's not a site where people sign up accounts. I'm going to end up making the create user method restricted by an already logged in user, but of course, when I clear the DB I can't create a user, so I have to prepopulate it somehow. I tried just making a migration to put a dump of a user I created but that doesn't work and seems pretty hacky. What's the best way to handle this? It's tricky since the passwords get hashed, so I feel like I have to create one and then pull out the hashed entries...
Rails 2.3.4 adds a new feature to seed databases.
You can add in your seed in db/seed.rb file:
User.create(:username => "admin", :password => "notthis", :password_confirmation => "notthis", :email => "admin#example.com")
Then insert it with:
rake db:seed
for production or test
RAILS_ENV="production" rake db:seed
RAILS_ENV="test" rake db:seed
My favorite feature in 2.3.4 so far
If you are using >= Rails 2.3.4 the new features include a db/seeds.rb file. This is now the default file for seeding data.
In there you can simple use your models like User.create(:login=>"admin", :etc => :etc) to create your data.
With this approach rake db:setup will also seed the data as will rake db:seed if you already have the DB.
In older projects I've sometimes used a fixture (remeber to change the password straight away) with something like users.yml:
admin:
id: 1
email: admin#domain.com
login: admin
crypted_password: a4a4e4809f0a285e76bb6b35f97c9323e912adca
salt: 7e8455432de1ab5f3fE0e724b1e71500a29ab5ca
created_at: <%= Time.now.to_s :db %>
updated_at: <%= Time.now.to_s :db %>
rake db:fixtures:load FIXTURES=users
Or finally as the other guys have said you have the rake task option, hope that helps.
Most used approach is to have a rake task that is run after deployment to host with empty database.
Add a rake task:
# Add whatever fields you validate in user model
# for me only username and password
desc 'Add Admin: rake add_admin username=some_admin password=some_pass'
task :add_admin => :environment do
User.create!(:username=> ENV["username"], :password=> ENV["password"],:password_confirmation => ENV["password"])
end