2011-03-15 2 views
2

J'ai commencé à déployer ma dernière application RoR sur Heroku, ce qui m'a obligé à commencer à utiliser PostgreSQL - j'avais précédemment utilisé SQLite et MySQL. Je voulais un moyen mort-simple de faire continuellement des tests rouges/verts sur les trois bases de données pour m'assurer que je n'ai rien cassé dans le feu de l'action.RoR: comment tester mon application sur plusieurs bases de données?

Quelle est une bonne façon de faire cela?

+1

Y a-t-il une question? –

+1

c'est une question avec une réponse (ce qui est légitime selon la faq). Je pensais que d'autres pourraient trouver cela utile. –

+1

Non, c'est question + réponse dans la partie question. Veuillez répondre à votre propre question ci-dessous ("Votre réponse") et acceptez cette réponse. De cette façon, cela va passer de la file d'attente sans réponse. Merci! – awendt

Répondre

0

@awendt a aimablement fait remarquer que je pouvais répondre à ma propre question.

Il s'avère que la recette est plutôt simple. Le secret est d'utiliser une variable d'environnement pour dire à Rails quelle base de données vous voulez utiliser.

1. Modifier vos fichiers

En config/database.yml, comprennent des constructions ERB comme ceci:

test: 
<% if (ENV["RAILS_DB"] == "PostgreSQL") %> 
    adapter: postgresql 
    encoding: unicode 
    database: bd_test 
    pool: 5 
    username: <%= ENV['POSTGRESQL_USERNAME'] || 'root' %> 
    password: <%= ENV['POSTGRESQL_PASSWORD'] || '' %> 
<% elsif (ENV["RAILS_DB"] == "MySQL") %> 
    adapter: mysql 
    encoding: utf8 
    reconnect: false 
    database: bd_test 
    pool: 5 
    username: <%= ENV['MYSQL_USERNAME'] || 'root' %> 
    password: <%= ENV['MYSQL_PASSWORD'] || '' %> 
    socket: <%= ENV['MYSQL_SOCKET'] || '/tmp/mysql.sock' %> 
<% else %> 
    # default to SQLite 
    adapter: sqlite3 
    database: db/test.sqlite3 
    pool: 5 
    timeout: 5000 
<% end %> 

Note 1: Je l'ai seulement montré pour l'environnement de test. En fait, c'est le seul que j'ai modifié, car (supposément) il fournit une couverture suffisante pour me dire si les trois bases de données sont correctement supportées.

Note 2: Vous n'avez pas besoin d'utiliser des variables d'environnement pour définir le nom d'utilisateur et le mot de passe - c'est juste quelque chose que je préfère faire car cela évite d'exposer les mots de passe.

De même, étendre Gemfile comme suit (notez que vos numéros de version peuvent varier):

source 'http://rubygems.org' 
gem 'rails', '3.0.3' 
case ENV["RAILS_DB"] 
when "PostgreSQL" 
    gem 'pg', '0.10.0' 
when "MySQL" 
    gem 'mysql2' 
else 
    gem 'sqlite3', '1.3.3' 
    gem 'sqlite3-ruby', '1.3.3', :require => 'sqlite3' 
end 
... 

2. Ajouter des conditions à votre code

Malgré les efforts de l'équipe de développement Rails, il y a quelques points où les constructions ActiveRecord ne sont pas compatibles entre toutes les variantes de base de données. Dans ces cas, vous pouvez conditionner votre code sur ActiveRecord::Base.connection.adapter_name. Voici un exemple d'un de mes fichiers de migration:

file: migrate/20110129023453_create_cached_web_pages.rb

def self.up 
    create_table :cached_web_pages do |t| 
    t.string :key    
    if ActiveRecord::Base.connection.adapter_name == "PostgreSQL" 
     t.binary :value 
    else 
     t.binary :value, :limit => 16777215 
    end 
    end 
end 
... 

3. Exécution et test

Vous pouvez maintenant sélectionner une base de données simplement en définissant la variable d'environnement RAILS_DB, mais il y a un hic: vous devez exécuter bundle install chaque fois pour configurer l'adaptateur de base de données approprié à partir de Gemfile. Heureusement, c'est exactement ce que fait le code de test. Ainsi, par exemple, je peux courir le test automatique de rspec en deux fenêtres:

$ RAILS_DB=SQLite autotest 

et

$ RAILS_DB=PostgreSQL autotest 

Maintenant je peux pirater loin à mes fichiers et Autotest me alerter tranquillement si j'ai rien cassé comme Je vais le long.

Questions connexes