J'ai une application Rails où les utilisateurs doivent se connecter. Par conséquent, pour que l'application soit utilisable, il doit y avoir un utilisateur initial dans le système pour que la première personne puisse se connecter avec (ils peuvent ensuite créer des utilisateurs ultérieurs.) Jusqu'à présent, j'ai utilisé une migration pour ajouter un utilisateur spécial à la base de données.
Après avoir demandé cette question , il semble que je devrais utiliser db: schema: load, plutôt que d'exécuter les migrations, pour configurer de nouvelles bases de données sur de nouvelles machines de développement. Malheureusement, cela ne semble pas inclure les migrations qui insèrent des données, seulement celles qui configurent des tables, des clés, etc.
Ma question est, quelle est la meilleure façon de gérer cette situation:
Je pensais que je résumerais certaines des bonnes réponses que j'ai eues à cette question, ainsi que mes propres pensées maintenant je les ai toutes lues :)
Il y a deux problèmes distincts ici:
Pour (1), il semble que la configuration du premier utilisateur à partir de l'application elle-même soit un travail supplémentaire, pour des fonctionnalités qui, par définition, sont rarement utilisées. Cependant, il peut être légèrement plus sécurisé, car il oblige l'utilisateur à définir un mot de passe de son choix. La meilleure solution se situe entre ces deux extrêmes: avoir un script (ou tâche de râteau, ou autre) pour configurer l'utilisateur initial. Le script peut ensuite être configuré pour se remplir automatiquement avec un mot de passe par défaut pendant le développement et pour exiger la saisie d'un mot de passe pendant l'installation/le déploiement de la production (si vous souhaitez décourager un mot de passe par défaut pour l'administrateur).
Pour (2), il semble qu'il existe un certain nombre de bonnes solutions valables. Une tâche de rake semble être un bon moyen, et il existe des plugins pour rendre cela encore plus facile. Il suffit de parcourir certaines des autres réponses pour voir les détails de celles-ci :)
Essayez une tâche de râteau. Par exemple:
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
Utilisez db/seed.rb
présent dans toutes les applications Rails.
Alors que certaines réponses données ci-dessus de 2008 peuvent bien fonctionner, elles sont assez obsolètes et elles ne sont plus vraiment Rails convention).
Le remplissage des données initiales dans la base de données doit être effectué avec le fichier db/seed.rb
.
Cela fonctionne comme un fichier Ruby.
Pour créer et enregistrer un objet, vous pouvez faire quelque chose comme:
User.create(:username => "moot", :description => "king of /b/")
Une fois que ce fichier est prêt, vous pouvez suivre
rake db:migrate
rake db:seed
Ou en une seule étape
rake db:setup
Votre base de données doit être remplie avec les objets que vous souhaitez créer dans seed.rb
Je vous recommande de ne pas insérer de nouvelles données dans les migrations. Au lieu de cela, modifiez uniquement les données existantes dans les migrations.
Pour insérer des données initiales, je vous recommande d'utiliser YML. Dans chaque projet Rails que je configure, je crée un répertoire fixtures sous le répertoire DB. Ensuite, je crée des fichiers YML pour les données initiales tout comme les fichiers YML sont utilisés pour les données de test. Ensuite, j'ajoute un nouvelle tâche pour charger les données à partir des fichiers YML.
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: "[email protected]"
hashed_password: "656fc0b1c1d1681840816c68e1640f640c6ded12"
salt: "188227600.754087929365988"
Ceci est ma nouvelle solution préférée, en utilisant les gemmes populator et faker:
Essayez le plugin seed-f , qui est un plugin assez simple qui vous permet de semer des données (et de changer ces données de semence à l'avenir), vous permettra également de semer des données spécifiques à l'environnement et des données pour tous les environnements .
Je suppose que la meilleure option est le numéro 3, principalement parce que de cette façon, il n'y aura pas d'utilisateur par défaut, ce qui est un excellent moyen de rendre inutile une bonne sécurité.
Pensez à utiliser la console Rails. Idéal pour les tâches d'administration ponctuelles où cela ne vaut pas la peine de configurer un script ou une migration.
Sur votre machine de production:
script/console production
... puis ...
User.create(:name => "Whoever", :password => "whichever")
Si vous générez cet utilisateur initial plus d'une fois, vous pouvez également ajouter un script dans Rails_ROOT/script/et l'exécuter à partir de la ligne de commande sur votre machine de production, ou via une tâche capistrano.
Excellent article de blog sur ce sujet: http://railspikes.com/2008/2/1/loading-seed-data
J'utilisais les suggestions de Jay d'un ensemble spécial d'appareils, mais je me suis rapidement retrouvé à créer des données qui ne seraient pas possibles en utilisant directement les modèles (entrées non versionnées lorsque j'utilisais actes_as_versioned)
Cette tâche Rake peut être fournie par le plugin db-populate:
Pour les utilisateurs et les groupes, la question des utilisateurs préexistants doit être définie par rapport aux besoins de l'application plutôt qu'aux aléas de la programmation. Peut-être que votre application nécessite un administrateur; puis préremplissez. Ou peut-être pas - puis ajoutez du code pour demander gracieusement une configuration utilisateur au moment du lancement de l'application.
Sur la question plus générale, il est clair que de nombreuses applications Rails peuvent bénéficier d'une date préremplie. Par exemple, une application détenant une adresse aux États-Unis peut également contenir tous les États et leurs abréviations. Pour ces cas, les migrations sont ton ami, je crois.
Je le garderais dans une migration. Bien qu'il soit recommandé d'utiliser le schéma pour les configurations initiales, la raison en est qu'il est plus rapide, évitant ainsi les problèmes. Une seule migration supplémentaire pour les données devrait convenir.
Vous pouvez également ajouter les données dans le fichier de schéma, car il s'agit du même format que les migrations. Vous perdriez simplement la fonction de génération automatique.
Certaines réponses sont dépassées. Depuis Rails 2.3.4, il existe une fonctionnalité simple appelée Seed disponible dans db/seed.rb
:
#db/seed.rb
User.create( :name => 'default', :password => 'password' )
Comment.create( :title => 'Title', :body => 'First post!' )
Il fournit une nouvelle tâche de râteau que vous pouvez utiliser après vos migrations pour charger des données:
rake db:seed
Seed.rb est un classique Ruby, n'hésitez pas à utiliser n'importe quelle infrastructure de données classique (tableau, hachages, etc.) et des itérateurs pour ajouter vos données:
["bryan", "bill", "tom"].each do |name|
User.create(:name => name, :password => "password")
end
Si vous souhaitez ajouter des données avec des caractères UTF-8 (très courant en français, espagnol, allemand, etc.), n'oubliez pas d'ajouter au début du fichier:
# Ruby encoding: utf-8
Ce Railscast est une bonne introduction: http://railscasts.com/episodes/179-seed-data