what is the seeds.rb in db folder in Ruby on Rails ? - ruby-on-rails

what is the relationship between db/seeds.rb and db/schema.rb? And How do I use them ? by the way,
# db/seeds.rb
Todo.create!(title: 'grocery shopping', notes: 'pickles, eggs, red onion')
Todo.create!(title: 'wash the car')
Todo.create!(title: 'register kids for school', notes: 'Register Kira for Ruby Junior High and Caleb for Rails High School')
Todo.create!(title: 'check engine light', notes: 'The check engine light is on in the Tacoma')
Todo.create!(title: 'dog groomers', notes: 'Take Pinky and Redford to the groomers on Wednesday the 23rd')
I can't understand 'notes'

The seed.rb helps you to initialize data into your db.
You can run the file by:
rake db:seed
or run
rake db:setup
to create db, run migrations, and run seed

Let's say you create a db and you can fill it with seeds.rb. In other words, you fill your tables in accordance with the model you generated beforehand.
User.create (username: "tony", password: "12345666")
User.create (username: "Clara", password: "fdvfdvfd666")
User.create (username: "Hans", password: "1gbfdbg2345666")

Related

How do I seed my database with only part of my seed code?

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.

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: "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/

Rails 3.1.0: Run Insert Script while doing rake db:migrate

I have created some table and I want to insert some data into the table. How shall I place my code when I commit the code and some of my peers pull the code and run rake db:migrate then on their db tables should be created along with the data?
You should use seeds
As it says in db/seeds.rb add in ruby code and then run rake db:seed
5.times do |i|
Product.create(name: "Product ##{i}", description: "A product.")
end

ruby-on-rails: Seeding-data strategies (or loading test data into developer database)

I want to clear and re-load my developer database (Ruby on rails) frequently.
Of course, I can manually add the data via the web page but I was wondering if anyone has any strategies for this type of testing.
(I already have unit, functional and integration tests, fyi)
Thanks
Create a seed.yml file in db directory. Add a YAML document for each model you want to create. This document should contain a list of hash. Each hash should contain model attributes.
users:
- login: jake
password: jake123
password_confirmation: jake123
first_name: Jake
last_name: Driver
- login: Jane
password: jane123
password_confirmation: jane123
first_name: Jane
last_name: McCain
categories:
products:
In your seed.rb file
seed_file = File.join(Rails.root, 'db', 'seed.yml')
config = YAML::load_file(seed_file)
User.transaction do
config.keys.each{ |key| key.classify.constantize.create(config[key]) }
end
I find it easier to modify the seed data in the YML file. Application that I have built is deployed by a different team. They like this approach too.
To clear the data I have a rake task in lib\tasks directory. I run the rake task as app:flush.
namespace :app do
desc "Flush all the seed data "
task :flush => :environment do
config = YAML::load_file(File.join(Rails.root, 'db', 'seed.yml'))
User.transaction do
config.keys.each{ |table| truncate_table(table)}
end
end
end
Time to look at "fixtures" and "seeding data" ;-) I am not good enough to give you a clear explanation, but googling those two keys should give you all you need.
Check these out: http://derekdevries.com/2009/04/13/rails-seed-data/
http://lptf.blogspot.com/2009/09/seed-data-in-rails-234.html

prepopulating admin user in database with authlogic rails plugin

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

Resources