Cela peut-il être fait? Dans une seule application, qui gère de nombreux projets avec SQLite . Ce que je veux, c'est une base de données différente pour chaque projet géré par mon application ... donc plusieurs copies d'une base de données de structure identique, mais contenant des données différentes. Je choisirai quelle copie utiliser sur la base des paramètres de l'URI.
Ceci est fait pour 1. la sécurité .. Je suis un novice dans ce type de programmation et je ne veux pas que, pour une raison quelconque, tout en travaillant sur un projet, un autre soit corrompu .. 2. sauvegarde et archivage faciles de anciens projets
Par défaut, Rails n'est pas conçu pour une architecture à plusieurs bases de données et, dans la plupart des cas, cela n'a aucun sens.
Voici quelques références:
Si vous êtes en mesure de contrôler et de configurer chaque instance Rails et que vous pouvez vous permettre de gaspiller des ressources en raison de leur mise en veille, évitez les problèmes et changez simplement le database.yml pour modifier la connexion à la base de données utilisée sur chaque instance. Si vous êtes préoccupé par les performances, cette approche ne suffira pas.
Pour les modèles liés à une seule table unique sur une seule base de données, vous pouvez appeler Establ_connection à l'intérieur du modèle:
establish_connection "database_name_#{Rails_ENV}"
Comme décrit ici: http://apidock.com/Rails/ActiveRecord/Base/establish_connection/class
Certains modèles utilisent des tables d’une base de données et d’autres modèles utilisent des tables d’autres bases de données.
Si vous avez des tables identiques, communes sur différentes bases de données et partagées par un seul modèle, ActiveRecord ne vous aidera pas. En 2009, j'avais besoin de cela pour un projet sur lequel je travaillais, utilisant Rails 2.3.8. J'avais une base de données pour chaque client et j'ai nommé les bases de données avec leurs identifiants. J'ai donc créé une méthode pour changer la connexion dans ApplicationController:
def change_database database_id = params[:company_id]
return if database_id.blank?
configuration = ActiveRecord::Base.connection.instance_eval { @config }.clone
configuration[:database] = "database_name_#{database_id}_#{Rails_ENV}"
MultipleDatabaseModel.establish_connection configuration
end
Et ajouté cette méthode en tant que before_filter à tous les contrôleurs:
before_filter :change_database
Ainsi, pour chaque action de chaque contrôleur, lorsque params [: id_entreprise] est défini et défini, la base de données sera remplacée par la bonne.
Pour gérer les migrations, j'ai étendu ActiveRecord :: Migration, avec une méthode qui recherche tous les clients et itère un bloc avec chaque ID:
class ActiveRecord::Migration
def self.using_databases *args
configuration = ActiveRecord::Base.connection.instance_eval { @config }
former_database = configuration[:database]
companies = args.blank? ? Company.all : Company.find(args)
companies.each do |company|
configuration[:database] = "database_name_#{company[:id]}_#{Rails_ENV}"
ActiveRecord::Base.establish_connection configuration
yield self
end
configuration[:database] = former_database
ActiveRecord::Base.establish_connection configuration
end
end
Notez qu'en faisant cela, il vous serait impossible de faire des requêtes dans la même action à partir de deux bases de données différentes. Vous pouvez appeler change_database à nouveau, mais cela deviendra désagréable si vous essayez d'utiliser des méthodes qui exécutent des requêtes, à partir des objets qui ne sont plus liés à la base de données correcte. De plus, il est évident que vous ne pourrez pas joindre des tables appartenant à différentes bases de données.
Pour gérer cela correctement, ActiveRecord doit être considérablement étendu. Il devrait déjà y avoir un plugin pour vous aider avec ce problème. Une recherche rapide m'a donné celui-ci:
DB-Charmer: http://kovyrin.github.com/db-charmer/
Je suis prêt à l'essayer. Faites-moi savoir ce qui fonctionne pour vous.
Je l'ai dépassé en ajoutant ceci au sommet de mes modèles en utilisant l'autre base de données
class Customer < ActiveRecord::Base
ENV["Rails_ENV"] == "development" ? Host = 'devhost' : Host = 'prodhost'
self.establish_connection(
:adapter => "mysql",
:Host => "localhost",
:username => "myuser",
:password => "mypass",
:database => "somedatabase"
)
Vous devriez également consulter ce projet appelé DB Charmer: http://kovyrin.net/2009/11/03/db-charmer-activerecord-connection-magic-plugin/
DbCharmer est un plugin simple mais puissant pour ActiveRecord qui fait quelques choses:
- Permet de gérer facilement les connexions des modèles AR (méthode
switch_connection_to
)- Permet de basculer les connexions par défaut des modèles AR sur un serveur/une base de données distinct
- Vous permet de choisir facilement où votre requête doit aller (famille de méthodes
on_*
)- Vous permet d'envoyer automatiquement des requêtes de lecture à vos esclaves tandis que les maîtres gèrent toutes les mises à jour.
- Ajoute plusieurs migrations de bases de données à ActiveRecord
Il convient de noter que dans toutes ces solutions, vous devez vous rappeler de fermer les connexions de base de données personnalisées. Vous serez à court de connexions et voyez les problèmes étranges de dépassement de délai de demande autrement.
Une solution simple consiste à clear_active_connections! dans un filtre after_filter de votre contrôleur.
after_filter :close_custom_db_connection
def close_custom_db_connection
MyModelWithACustomDBConnection.clear_active_connections!
end
La meilleure solution que j'ai trouvée jusqu'à présent est la suivante:
Il y a 3 architectures de base de données que nous pouvons approcher.
Remarque: ils ont certains avantages et inconvénients dépend de votre cas d'utilisation.
Je viens de ceci Blog ! Se tient très utile pour moi.
Vous pouvez utiliser le joyau Appartement pour Rails
Vous pouvez suivre la référence vidéo sur Gorails for apartment
Ce que vous avez décrit dans la question est la multi-organisation (bases de données structurées de manière identique avec des données différentes dans chacune). Le appartement bijou est idéal pour cela.
Pour la question générale de plusieurs bases de données dans Rails: ActiveRecord prend en charge plusieurs bases de données, mais Rails ne permet pas de les gérer. J'ai récemment créé le Multiverse gem pour résoudre ce problème.
dans votre config/database.yml faire quelque chose comme ça
default: &default
adapter: postgresql
encoding: unicode
pool: 5
development:
<<: *default
database: mysite_development
test:
<<: *default
database: mysite_test
production:
<<: *default
Host: 10.0.1.55
database: mysite_production
username: postgres_user
password: <%= ENV['DATABASE_PASSWORD'] %>
db2_development:
<<: *default
database: db2_development
db2_test:
<<: *default
database: db2_test
db2_production:
<<: *default
Host: 10.0.1.55
database: db2_production
username: postgres_user
password: <%= ENV['DATABASE_PASSWORD'] %>
alors dans vos modèles, vous pouvez référencer db2 avec
class Customers < ActiveRecord::Base
establish_connection "db2_#{Rails.env}".to_sym
end