I'm about to add in a few users manually (because I want to make them admins eg user.admin = true. Previously, in development I've done this using seeds but I believe (correct me if I'm wrong) that you aren't supposed to use seeds in this way in production. What else should I do?
There are a number of options, each with their own pros and cons.
Set up the users in the Rails console
Advantage: simple, can customize as much as needed
Disadvantage: not reproducible
Add users in a migration
Advantage: if this is a new table or relevant data exists in other tables, you can set up the new data right away as part of a migration
Disadvantage: not a standard use of migration scripts
Set up users with a rake task
Advantage: code to reproduce your steps will be checked into your repo
Disadvantage: if you only want to do this once, a rake task is overkill
The best solution might be to add a script in the scripts/ directory of your app detailing the steps, have this code reviewed by your team, and then run it with rails runner.
Do you have access to the production command line? If you're using Heroku you can do this:
$ heroku run rails console
> user = User.new
> user.name = "The name"
// repeat for all other fields
> user.admin = true
> user.save
Or if you already have them in the database as non-admins
$ heroku run rails console
> user = User.find_by(name: "Their Name")
> user.update_attribute(:admin, true)
I have a new rails app with a fresh database and I want to add some default entries, like admin with default password etc.
How should I proceed?
I know of two possibilities, that both have drawbacks:
Use ruby code in migration: User.create!(:email => "admin#example.com", :password => "abc")
Use SQL code in migration: INSERT INTO users (id, email, password) VALUES (1, 'admin#example.com', 'abc')
The first alternative can break if I alter my code in later versions. The second is somewhat DBMS dependent.
As I do not plan to change my database, I would go with SQL code, but are there better alternatives?
Personally I'd use seed data
http://railscasts.com/episodes/179-seed-data
One advantage of this is that rake db:setup calls rake db:seed after it has created the database. Which is perfect for new machines.
The best way is to use Ruby code in db/seeds.rb.
The comment at the start of that file says:
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).
This is preferred over putting initialization code in the migration files.
I use the seed_fu gem, I haven't run into anything yet that it couldn't handle for me:
https://github.com/mbleigh/seed-fu
I am using Ruby on Rails v3.0.9 and I have a web application running in production mode. I would like to change and add some data in the database (also, I would like to make that these data changes take effect in development mode - that is, for example, that the added data should be present also in development mode when I am running and developing my application on my local machine)...
... what is "the best way"\"the most commonly used approach" to do that? I mean, for example, should I create a migration file with in some User.create(:name => '...', :surname => '...', ...) statements and run those or there are other ways to accomplish what I would like to do?
Note: I do not need to populate the database with initial data (I already made that in the seed.rb file). I just need to update and add database table rows.
seed.rb should be use only for initial set of values.
rake task should be use only when you want to update data any existing columns.
migration should be use when you need to change the schema of the table.
You should use the file db/seed.rb to accomplish this task
Here is an example on how to use it: http://asciicasts.com/episodes/179-seed-data
This may be my most stupid question yet:
I've implemented this tutorial on my Rails 3 app to get Devise up and running with CanCan. What is the right way to enter the first record in your development database, when only admins are allowed to enter a record and a null record isn't allowed? Do you just hack away some of the code to reduce permissions, then put it back again?
Update: to add to the answer, if you put this in seeds.db it works, even though there's no password field in the User table:
User.create(:email => 'me#mysite.com',:password => 'secret')
Use db/seeds.rb to write the code for your admin record. And call rake db:seed to execute that. Make sure you check whether the initial records are already created, so that running rake db:seed won't duplicate the data.
I've got a rails application where users have to log in. Therefore in order for the application to be usable, there must be one initial user in the system for the first person to log in with (they can then create subsequent users). Up to now I've used a migration to add a special user to the database.
After asking this question, it seems that I should be using db:schema:load, rather than running the migrations, to set up fresh databases on new development machines. Unfortunately, this doesn't seem to include the migrations which insert data, only those which set up tables, keys etc.
My question is, what's the best way to handle this situation:
Is there a way to get d:s:l to include data-insertion migrations?
Should I not be using migrations at all to insert data this way?
Should I not be pre-populating the database with data at all? Should I update the application code so that it handles the case where there are no users gracefully, and lets an initial user account be created live from within the application?
Any other options? :)
Try a rake task. For example:
Create the file /lib/tasks/bootstrap.rake
In the file, add a task to create your default user:
namespace :bootstrap do
desc "Add the default user"
task :default_user => :environment do
User.create( :name => 'default', :password => 'password' )
end
desc "Create the default comment"
task :default_comment => :environment do
Comment.create( :title => 'Title', :body => 'First post!' )
end
desc "Run all bootstrapping tasks"
task :all => [:default_user, :default_comment]
end
Then, when you're setting up your app for the first time, you can do rake db:migrate OR rake db:schema:load, and then do rake bootstrap:all.
Use db/seed.rb found in every Rails application.
While some answers given above from 2008 can work well, they are pretty outdated and they are not really Rails convention anymore.
Populating initial data into database should be done with db/seed.rb file.
It's just works like a Ruby file.
In order to create and save an object, you can do something like :
User.create(:username => "moot", :description => "king of /b/")
Once you have this file ready, you can do following
rake db:migrate
rake db:seed
Or in one step
rake db:setup
Your database should be populated with whichever objects you wanted to create in seed.rb
I recommend that you don't insert any new data in migrations. Instead, only modify existing data in migrations.
For inserting initial data, I recommend you use YML. In every Rails project I setup, I create a fixtures directory under the DB directory. Then I create YML files for the initial data just like YML files are used for the test data. Then I add a new task to load the data from the YML files.
lib/tasks/db.rake:
namespace :db do
desc "This loads the development data."
task :seed => :environment do
require 'active_record/fixtures'
Dir.glob(RAILS_ROOT + '/db/fixtures/*.yml').each do |file|
base_name = File.basename(file, '.*')
say "Loading #{base_name}..."
Fixtures.create_fixtures('db/fixtures', base_name)
end
end
desc "This drops the db, builds the db, and seeds the data."
task :reseed => [:environment, 'db:reset', 'db:seed']
end
db/fixtures/users.yml:
test:
customer_id: 1
name: "Test Guy"
email: "test#example.com"
hashed_password: "656fc0b1c1d1681840816c68e1640f640c6ded12"
salt: "188227600.754087929365988"
This is my new favorite solution, using the populator and faker gems:
http://railscasts.com/episodes/126-populating-a-database
Try the seed-fu plugin, which is quite a simple plugin that allows you to seed data (and change that seed data in the future), will also let you seed environment specific data and data for all environments.
I guess the best option is number 3, mainly because that way there will be no default user which is a great way to render otherwise good security useless.
I thought I'd summarise some of the great answers I've had to this question, together with my own thoughts now I've read them all :)
There are two distinct issues here:
Should I pre-populate the database with my special 'admin' user? Or should the application provide a way to set up when it's first used?
How does one pre-populate the database with data? Note that this is a valid question regardless of the answer to part 1: there are other usage scenarios for pre-population than an admin user.
For (1), it seems that setting up the first user from within the application itself is quite a bit of extra work, for functionality which is, by definition, hardly ever used. It may be slightly more secure, however, as it forces the user to set a password of their choice. The best solution is in between these two extremes: have a script (or rake task, or whatever) to set up the initial user. The script can then be set up to auto-populate with a default password during development, and to require a password to be entered during production installation/deployment (if you want to discourage a default password for the administrator).
For (2), it appears that there are a number of good, valid solutions. A rake task seems a good way, and there are some plugins to make this even easier. Just look through some of the other answers to see the details of those :)
Consider using the rails console. Good for one-off admin tasks where it's not worth the effort to set up a script or migration.
On your production machine:
script/console production
... then ...
User.create(:name => "Whoever", :password => "whichever")
If you're generating this initial user more than once, then you could also add a script in RAILS_ROOT/script/, and run it from the command line on your production machine, or via a capistrano task.
That Rake task can be provided by the db-populate plugin:
http://github.com/joshknowles/db-populate/tree/master
Great blog post on this:
http://railspikes.com/2008/2/1/loading-seed-data
I was using Jay's suggestions of a special set of fixtures, but quickly found myself creating data that wouldn't be possible using the models directly (unversioned entries when I was using acts_as_versioned)
I'd keep it in a migration. While it's recommended to use the schema for initial setups, the reason for that is that it's faster, thus avoiding problems. A single extra migration for the data should be fine.
You could also add the data into the schema file, as it's the same format as migrations. You'd just lose the auto-generation feature.
For users and groups, the question of pre-existing users should be defined with respect to the needs of the application rather than the contingencies of programming. Perhaps your app requires an administrator; then prepopulate. Or perhaps not - then add code to gracefully ask for a user setup at application launch time.
On the more general question, it is clear that many Rails Apps can benefit from pre-populated date. For example, a US address holding application may as well contain all the States and their abbreviations. For these cases, migrations are your friend, I believe.
Some of the answers are outdated. Since Rails 2.3.4, there is a simple feature called Seed available in db/seed.rb :
#db/seed.rb
User.create( :name => 'default', :password => 'password' )
Comment.create( :title => 'Title', :body => 'First post!' )
It provides a new rake task that you can use after your migrations to load data :
rake db:seed
Seed.rb is a classic Ruby file, feel free to use any classic datastructure (array, hashes, etc.) and iterators to add your data :
["bryan", "bill", "tom"].each do |name|
User.create(:name => name, :password => "password")
end
If you want to add data with UTF-8 characters (very common in French, Spanish, German, etc.), don't forget to add at the beginning of the file :
# ruby encoding: utf-8
This Railscast is a good introduction : http://railscasts.com/episodes/179-seed-data