77 votes

Rails 3.1 avec Plusieurs Bases de données

Au ShowNearby nous avons fait une très grande migration à RoR 3.1 à partir de PHP et nous sommes confrontés à plusieurs problèmes que peut être certains d'entre vous ont résolu avant.

Nous avons de grandes quantités de données et nous avons décidé de nous séparer de notre DB en plusieurs DBs que l'on peut traiter séparément. Par exemple, nos comptes, des lieux, des journaux et d'autres sont divisés en plusieurs bases de données

Nous avons besoin d'obtenir des migrations, des luminaires, des modèles, de jouer gentiment, et jusqu'à présent, il a été assez chaotique. Certains de nos exigences pour qu'une solution soit acceptable:

  • un modèle doit correspondre à une des tables dans une base de données.
  • rake db:drop - doivent abandonner toutes la base de données env nous spécifier dans la base de données.yml
  • rake db:create - créez tous la base de données env nous spécifier dans la base de données.yml
  • rake db:migrate - doit exécuter les migrations aux différentes bases de données
  • rake db:essai doit saisir les luminaires et les déposer dans les diverses bases de données et de l'unité de test, de fonction, etc

Nous envisageons de réglage séparé des rails de projets par chaque base de données et de les connecter avec ActiveResource, mais nous pensons que cela n'est pas très efficace. N'avez-vous affaire avec un problème semblable?

Merci beaucoup!!

142voto

Unixmonkey Points 7947

Pour Wukerplank réponse, vous pouvez aussi mettre les détails de connexion dans la base de données.yml comme d'habitude avec un nom comme ceci:

log_database_producion:
  adapter: mysql
  host: other_host
  username: logmein
  password: supersecret
  database: logs

Puis dans votre modèle spécial:

class AccessLog < ActiveRecord::Base
  establish_connection "log_database_#{Rails.env}"
end

Pour garder ces satanés informations d'identification dans le code de votre application.

Edit: Si vous souhaitez réutiliser cette connexion dans plusieurs modèles, vous devez créer une nouvelle classe abstraite et hériter d'elle, parce que les connexions sont étroitement associés aux classes (comme expliqué ici, ici, et ici), et de nouvelles connexions seront créés pour chaque classe.

Si c'est le cas, mettre les choses en place comme suit:

class LogDatabase < ActiveRecord::Base
  self.abstract_class = true
  establish_connection "log_database_#{Rails.env}"
end

class AccessLog < LogDatabase
end

class CheckoutLog < LogDatabase
end

18voto

Wukerplank Points 3164

Connexion à plusieurs bases de données est très simple:

# model in the "default" database from database.yml
class Person < ActiveRecord::Base

  # ... your stuff here

end

# model in a different database
class Place < ActiveRecord::Base

  establish_connection (
    :adapter  => "mysql",
    :host     => "other_host",
    :username => "username",
    :password => "password",
    :database => "other_db"
  )

end

Je me méfie de la configuration de plusieurs Rails de projets vous permettra d'ajouter beaucoup de surcharge de récupération de données pour vos contrôleurs, ce qui pourrait rendre les choses lentement.

Comme pour répondre à vos questions sur les migrations, des luminaires, des modèles, etc.: Je ne pense pas qu'il y aura un moyen facile, de sorte s'il vous plaît poster des questions séparées et être aussi précis que vous le pouvez.

La consolidation de la DBs dans l'un n'est pas une option? Il serait de rendre votre vie beaucoup plus facile!

11voto

TwoByteHero Points 129

Trouvé un super post qui va pointer les autres à la bonne façon de le faire vérifier http://blog.bitmelt.com/2008/10/connecting-to-multiple-database-in-ruby.html

Configurer quelque chose comme ceci:

la base de données.yml (db fichier de config)

support_development:
    adapter: blah
    database: blah
    username: blah
    password: blah

support_base.rb (un fichier de modèle)

class SupportBase < ActiveRecord::Base
    self.abstract_class = true #important!
    establish_connection("support_development")
end

tst_test.rb (un fichier de modèle)

class TstTest < SupportBase 
    #SupportBase not ActiveRecord is important!

    self.table_name = 'tst_test'

    def self.get_test_name(id)
        if id = nil
            return ''
        else
            query = "select tst_name from tst_test where tst_id = \'#{id}\'"
            tst = connection.select_all(query) #select_all is important!
            return tst[0].fetch('tst_name')
        end
    end
end

PS, ce n'est pas vraiment couvrir les migrations, je ne pense pas que vous pouvez faire des migrations sur plus d'un DB avec le râteau (bien que je ne suis pas sûr que c'est un dur "ne peut pas faire", il peut être possible). C'était juste un excellent moyen de se connecter et d'interroger d'autres DBs que vous n'avez pas de contrôle.

5voto

Kris Points 3781

Vous pouvez également ajouter les Rails de l'environnement, de sorte que votre test et de développement de bases de données ne sont pas les mêmes.

establish_connection "legacy_#{Rails.env}"

1voto

Rafael Points 121

Hey ce post est vieux, mais j'ai trouvé une solution de travail sur des Rails 3.2 qui pourrait aider quelqu'un d'autre. http://stackoverflow.com/a/16542724/1447654

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X