I need certain things to be seeded into a test environment, specifically, user roles from CanCan. BUT it seems to load everything under development.
lib/tasks/test _ seed.rake
namespace :db do
namespace :test do
task :prepare => :environment do
Rake::Task["db:seed"].invoke
end
end
end
which correctly pulls in seeds.rb after running bundle exec rake db:test:prepare
db/seeds.rb
admin = Role.create( { name: "admin" }, :without_protection => true)
user = Role.create( { name: "user" }, :without_protection => true)
if Rails.env.production? || Rails.env.development?
admin = User.create!({ name: "Admin",
email: "admin#example.com",
password: "foobar",
password_confirmation: "foobar",
role_ids: 1 },
:without_protection => true)
admin.confirm!
if Rails.env.development?
48.times do |n|
name = Faker::Name.name
email = "example-#{n+1}#example.com"
password = "foobar"
fake = User.create!({ name: name,
email: email,
password: password,
password_confirmation: password },
:without_protection => true)
fake.confirm!
end
end
end
All looks good but then........
$ rails console test
Loading test environment (Rails 3.2.8)
> User.first
User Load (1.0ms) SELECT "users".* FROM "users" LIMIT 1
=> #<User id: 1, email: "admin#example.com" ..................
> Rails.env.development?
=> false
What wrong?
You have to set the environment variable ENV to test before launching task.
Try executing:
$ RAILS_ENV=test rake db:seed
Maybe, you are using the same database for development and test environments. Check your database.yml
First of all, try to execute it in your terminal:
echo $RAILS_ENV
If it is showing test then you have your answer.
If is not, verify your config/database.yml to see if it is using the same database for both environments.
Verify also your config/environment.rb
Related
In rails, I wrote a task for automatically generate fake user
task fake_user: :environment do
User.destroy_all
filelink = ""
Dir.glob("#{Rails.root}/public/avatar/admin.jpg").map do |pic|
client = FilestackClient.new('ARz3g0HLfR5i0KuobcdJmz')
filelink = client.upload(filepath: pic)
end
admin = User.create(
email: "admin#example.com",
password: "admin123",
role: 'admin',
name: 'admin',
introduction: FFaker::Lorem::sentence(30),
avatar: filelink.url
)
puts admin.name
20.times do |i|
name = FFaker::Name::first_name
filelink = ""
Dir.glob("#{Rails.root}/public/avatar/user#{i+1}.jpg").map do |pic|
client = FilestackClient.new('ARz3g0HLfR5i0KuobcdJmz')
filelink = client.upload(filepath: pic)
end
user = User.create(
name: name,
email: "#{name}#example.co",
password: "12345678",
introduction: FFaker::Lorem::sentence(30),
avatar: filelink.url
)
user.save!
puts user.name
end
end
And there's no error when running in local.
But when I deploy it to Heroku, some errors happened
Here's the steps I did
Heroku run bundle install (correct)
Heroku run rails db:migrate (correct)
Heroku run rails dev:fake_user (error...)
Here's the error message I got
Hope someone can help me fix this.... thanks....
From logs it seems that your connection is disconnected. Have you tried following in database.yml ?
reconnect: true
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/
I have simple rails 2 composer app. I can rake migrate and seed the app locally fine and the admin user in the seed file is setup. However the db does not seed on Heroku. I get the following error (with trace when i run - heroku run rake db:setup --trace ):
** Execute db:abort_if_pending_migrations
ROLES
rake aborted!
can't convert nil into String
This is my code:
seed.rb
# This file should contain all the record creation needed to seed the database with its default values.
# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
#
# Examples:
#
# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
# Mayor.create(name: 'Emanuel', city: cities.first)
# Environment variables (ENV['...']) are set in the file config/application.yml.
# See http://railsapps.github.io/rails-environment-variables.html
puts 'ROLES'
YAML.load(ENV['ROLES']).each do |role|
Role.find_or_create_by_name({ :name => role }, :without_protection => true)
puts 'role: ' << role
end
puts 'DEFAULT USERS'
user = User.find_or_create_by_email :name => ENV['ADMIN_NAME'].dup, :email => ENV['ADMIN_EMAIL'].dup, :password => ENV['ADMIN_PASSWORD'].dup, :password_confirmation => ENV['ADMIN_PASSWORD'].dup
puts 'user: ' << user.name
user.add_role :admin
user.save!
application.yml
GMAIL_USERNAME: Your_Username
GMAIL_PASSWORD: Your_Password
ADMIN_NAME: First User
ADMIN_EMAIL: user#example.com
ADMIN_PASSWORD: changeme
ROLES: [admin, user]
I'm reasonably new to rails. The app did seed initially, but i've made some migrations and rolledback once.
Any help much appreciated.
if you trace role with a "db:reset --trace" and add "put role" like this :
YAML.load(ENV['ROLES']).each do |role|
puts role
You can see that the first role is admin, but after the rake db:reset put the message "uninitialized constant Role"
So the problem is not the ENV['ROLES'] !
after running rake db:reset
i rund rake db:populate and i'm getting this error don't know where it's coming from
rake aborted!
undefined method `+' for 4..5:Range
Tasks: TOP => db:populate
(See full trace by running task with --trace)
in my task folder
namespace :db do
desc " Fill database with sample data"
task populate: :environment do
admin = User.create!(name: "Emple User",
email: "exampel#railstuttorial.org",
password: "password",
password_confirmation: "password")
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
users = User.all(limit: 6)
50.times do
content = Faker::Lorem.sentence(4..5)
users.each { |user| user.microposts.create!(content: content) }
content = nil
end
end
end
You are passing a range to Faker::Lorem.sentence in your 50.times loop.
I'm not sure what you're trying to achieve but that method is expecting an integer (did you mean 4 or 5?) and when it tries to add something to it within the Faker::Lorem code it is causing that error.
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).