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
Related
On Rails 6, i expect rake db:setup to perform db:create, db:migrate and db:seed
i have only one data model and the record creation for its table was written in db/seeds.rb
# db/seeds.rb
require 'csv'
csv_text = File.read(Rails.root.join('lib', 'seeds', 'seed_first_table.csv'))
csv = CSV.parse(csv_text, :headers => true, :encoding => 'ISO-8859-1')
csv.each_with_index do |row, index|
cr = CatProfile.new
puts "row #{index} saved"
end
puts "There are now #{CatProfile.count} rows in the table"
database.yml also has a new user credential which was created through sudo -u postgres createuser -s new_user
But rake db:setup returns:
Created database 'my_application_development'
Created database 'my_application_test'
my_application/db/schema.rb doesn't exist yet. Run `rails db:migrate` to create it, then try again. If you do not intend to use a database, you should instead alter /my_application/config/application.rb to limit the frameworks that will be loaded.
in sudo -u postgres psql it did make the databases but there are no relations (no seed table)
when I run rails db:migrate
== 20201103153526 CreateCatProfiles: migrating =================================
-- create_table(:cat_profiles)
-> 0.0091s
== 20201103153526 CreateCatProfiles: migrated (0.0092s) ========================
then when I run rake db:setup a second time:
Database 'my_application_development' already exists
Database 'my_application_test' already exists
row 0 saved
row 1 saved
...
row 1719 saved
There are now 1720 rows in the table
noticed that database already exists from the first rake db:setup but now it is able to seed the table
I dont understand why running rake db:setup the first time does not pick up necessary migrations before seeding
If you check out the source code for rails db:setup you will see that db:setup does NOT run db:migrate
Creates the database, loads the schema, and initializes with the seed data (use db:reset to also drop the database first)
db:schema:load loads what currently exists in your schema.rb into the database.
Following the instructions in https://stackoverflow.com/a/24496452/102675 I wound up with the following:
namespace :db do
desc 'Drop, create, migrate, seed and populate sample data'
task seed_sample_data: [:drop, :create, :migrate, :seed, :populate_sample_data] do
puts 'Sample Data Populated. Ready to go!'
end
desc 'Populate the database with sample data'
task populate_sample_data: :environment do
puts Inspector.column_names.include?('how_to_fix')
# create my sample data
end
end
As you would expect, I get true if I run bundle exec rake db:populate_sample_data
BUT if I run bundle exec rake db:seed_sample_data I get all the migration output and then false. In other words I can't see the Inspector attribute how_to_fix even though it definitely exists as proved by the other rake run. Where did my attribute go?
My guess is that this is a "caching" problem. Can you try the following?
task populate_sample_data: :environment do
Inspector.reset_column_information
# ...
end
P.S. We used to have a similar problem working with different databases having the exact same schema (only except some columns here and there)
I use Rails4.
fixtures
I use fixtures for debug data.
but
$ bin/rake db:fixtures:load FIXTURES_PATH=spec/fixtures
not run before_validation and other callbacks.
factory_girl
I use factory_girl for test.
like
$ bundle exec rspec spec/models/foo_spec.rb.
seed
I know how to use factory_girl in seed
$ bundle exec rake db:seed
but I want to use seed for only master data.
Question
How to use factory_girl for debug data. and Do I use what command?(rake ?? or spec or something else?)
Make a rake task that uses your factories to create your debug data. For example, if you had a model (and corresponding factory) named Report:
namespace :db do
desc "Fill database with debug data"
task :debug_data => :environment do
puts "Destroy existing data?"
if STDIN.gets.chomp.upcase == 'Y'
if Rails.env.production?
raise "\nI'm sorry, Dave, I can't do that.\n(You're asking me to drop your production database.)"
end
Report.destroy_all
end
FactoryGirl.create(:report, name: 'Fred')
FactoryGirl.create(:report, name: 'Barney')
end
Place this file in: lib/tasks/debug_data.rake
Execute it using:
bundle exec rake db:debug_data
Is there any conventions of rails or a right way to create/manipulate a table that will contain just one row?
If not, what is the best way to do that?
I need a way to store configurations of the system.
Thanks.
Edited:
The rake db:seed command, basically execute whatever code you write in db/seeds.rb file of your application. Though can write any code in this file, by convention you should write code which populate your database with the basic data,
for example: when ever your deploy your application somewhere, and create a new database for it, you want that user with admin credential must be present there. So you will write the code which create that user in this file. Below is the sample code which will create a user and assign admin role to him.
puts "********Seeding Data Start************"
admin = User.create(:first_name => 'System', :last_name => 'Admin',
:email => 'systemadmin#sunpower.com', :password => 'sunpoweradmin',
:password_confirmation => 'sunpoweradmin', :source_system_id => 'systemadmin',
:source_system => 'LP',:entity_type => "Customer", :target_system => "OPENAM")
if admin.errors.blank?
puts "***User #{admin.first_name} #{admin.last_name} created ***"
admin.add_role :admin # add_role is method defined by rolify gem
puts "***admin role assigned to #{admin.first_name} #{admin.last_name}***"
else
puts "admin user failed to create due to below reasons:"
admin.errors.each do |x, y|
puts"#{x} #{y}" # x will be the field name and y will be the error on it
end
end
puts "********Seeding Data End************"
Now whenever you recreate your database, you just need to run below command to populate the database, with the basic data
$ rake db:seed RAILS_ENV=production
The correct order to setup database in production, with all the rake task available within db namespace is as below
$rake db:create RAILS_ENV=production
$rake db:migrate RAILS_ENV=production
$ rake db:seed RAILS_ENV=production
NOTE: You can replace the first two commands with $rake db:setup RAILS_ENV=production , it will run both create and migrate internally
OR
You could use the rails-settings-cached gem which is a fork of the rails-settings gem
Once setup, you'll be able to do things such as:
Setting.foo = 123
Setting.foo # returns 123
Hope this may help you or what you are looking for..
Project is the model name and I want to do something like:
Project.create(:name => 'projectname', :identifier => 'projectidentifier')
This should be done in the terminal through a ruby script. I am not going to use rails console to create it nor use seeds.rb in a db file to migrate this as rake db:seed.
Can someone help. Thanks
The easiest way would be using rails runner (which essentially loads rails):
rails runner your_script.rb
The line of code would be a content of that script.
What about a rake task?
on lib/tasks, create a file named data.rake, and the content:
namespace :data
desc "Create project data"
task create_project_data: :environment do
Project.create(name: 'projectname', identifier: 'projectidentifier')
end
end
And you can run it as any rake task
rake data:create_project_data
And it will also appear when you list your rake tasks
rake -T