学习 为Rails 配置外部数据库。
场景描述
Rails中,有model user和 article,article与user的关系是一对多,现在需要针对每一个User,列出所有ta发布的文章,而 article的数据来源于另一个外部的数据库,比如 works 。
怎么处理?
用establish_connection。
解决方法
拆解成两步:
- 为外部数据库建配置文件
- 为model和外部数据库建立连接
具体如下:
Step1、 新增文件config/works_database.yml
,内容如下:
# using another database
default: &default
adapter: mysql2
encoding: utf8
username: root
password:
host: localhost
pool: 5
development:
<<: *default
database: works_development
test:
<<: *default
database: works_test
production:
<<: *default
database: works_production
这里,假定数据库works_development是已经存在的,其实就是场景描述中的works数据库。
Step2、创建initializer去读取配置文件并存入环境变量中
在config/initializers/下,新增文件works_database.rb
,内容如下:
WORKS_DB = YAML.load_file(File.join(Rails.root.join('config','works_database.yml')))[Rails.env.to_s]
这样,我们外部数据库的配置信息就会存储在WORKS_DB中了。
Step3、 创建一个基类来处理数据库的连接
新建文件app/models/works_database.rb
,放入以下内容:
class WorksDatabase < ApplicationRecord
self.abstract_class = true
establish_connection WORKS_DB
end
establish_connection是ActiveRecord::Base的一个类方法,由于WorksDatabase继承自ApplicationRecord,所以可以直接调用,它的作用就是用于连接数据库的。
Step4、 将需要连接到WORKS_DB的model都继承自WorksDatabase
修改app/models/article.rb
:
class Article < WorksDatabase
belongs_to :user
end
OK !
Step 3 和Step 4其实可以合并成一步,直接在app/models/article.rb
中修改成如下:
class Article < ActiveRecord::Base
belongs_to :user
establish_connection WORKS_DB
end
但是这种一般在只有一个或少数几个model需要用到外部数据库时使用的较多,当存在多个models的时候,则推荐用baseclass的方式,把establish_connection封装起来,其他类直接继承该基类即可。即遵守DRY原则。