Ruby Rails 源码笔记

lhy20062008 · 2014年03月31日 · 最后由 lang1pal 回复于 2014年03月31日 · 3055 次阅读

最近由于工作需要,只能通过阅读 rails 源码来解决遇到的问题,特记录如下:(若有不正确的地方,还望各位大神提出来,并多多指导小弟) 先说说问题吧: 1、同一个项目需要将原有数据库拆分成两个不同的数据库,而且能需要保证不同数据库的各使用一个相同的链接,由于我们两项目都需要做这样的拆分,且项目 A 是 rails 3.2 版本,项目 B 是 rails 2 版本,因此遇到了问题: rails 3 拆分之后,通过 include 就可以访问新的数据库,而在项目 B 中,只有最先访问的表访问的是新的数据库,其他表访问的是之前的数据库(这里先约定之前的数据库有拆分出来的数据库的所有表) 解决方式: 通过查看 rails2 和 rails3 的源码,发现有以下区别: rails 3: 通过 connection_pools 保存数据库连接池,为 hash,每个数据库连接池用数据库配置 spec 作为关键字,并通过实例变量 class_pools 保存每个模型对应的链接,为 hash,关键字为模型名 name,值 connection_pools[spec],这样就能保证同一个数据库的模型用的是同一个链接,且与其他数据库不一样; 如:connection_pools[spec] = connection, class_pools[name1] = class_pools[name2] = connection

rails2: 通过 connection_pools 保存数据库连接池,为 hash,每个数据库连接池用模型名 name 作为关键字,而且如果是不同的模型,就会 new 一个新的链接,导致每个模型使用的是不同的链接,如:connection_pools[name1] = connection1, connection_pools[name2] = connection2

模型查找链接的方式: 先通过模型名在 class_pools 中查找,如果找到即返回,否则查询其父类的链接,一般情况下 ActiviteRecord::Base 都会有一个默认的链接;

因此 rails2 中提供了一种方式解决该问题:在新数据库创立链接,并使其中所有模型都继承该 base_model,这样所有模型都用 base_model 的链接。

但是由于领导要求不采用这种方式(主要是这种继承关系很牵强,没有实际的意义),反复研究,终于让我找到了另一种方式,就是模仿 rails3 在新的数据库连接创立的时候记录一个类变量,并且只要创建一次就不再创建,每个模型 include 这些代码,并对每个模型维持一个 hash 值:connetion[name_n] = (@@connection ||=(create connection)) 这样处理之后,每次模型区查找链接的时候都会在 connection_pools 中查找到 @@connection,而且该数据库下每个模型都是使用的一个链接,问题得到结局。

ps:带着问题去阅读源码是一个不错的学习方式

赶脚你这么做很勉强。Rails3 和 Rails2 两个项目以及数据库高度耦合。现在是能转了,将来改动的时候就头疼了。另外你使用了 module variable, 是否对 thread 友好还不得而知。

经常看到有项目是多个数据库的。我有一个疑问,我觉得在使用多个数据库的情况下,使用 MySQL Proxy(数据库代理层)之类的中间层再去访问数据库是否能更方便点。这样就不用再修改源代码然后做拆分数据库之类的工作。 我觉得这样会更方便点,或者说这样做会不会有什么弊端

需要 登录 后方可回复, 如果你还没有账号请 注册新账号