惟愿终日无丝竹之乱耳,无案牍之劳形。看那平心所至处,皆为仙境。

用method_missing来兼容旧数据库

上一篇 / 下一篇  2007-08-26 01:45:20 / 个人分类:搞搞技术

查看( 20 ) / 评论( 3 )
原文首发:Ruby中文社区
社区地址:http://www.ruby-lang.org.cn/
转载请保留版权声明并以连接形式指向原文。



这几天写个小东西,数据库是早就建立好的,没有办法更改,而且还有其它程序依赖于这个数据库,所以没有办法,只好在Rails上动手脚了。

数据库结构大概如下:
1. 所有表名皆有统一前缀。
2. 所有字段名皆有前缀,大部分字段名的前缀与表名的单数形式一致,但有的为表名的简写。

想像一下,我们如果不做任何改变写出来的代码会是什么样子的。

CODE:

f = Forum.new
f.forum_name = 'My Forum'
f.forum_date_created = Time.now
f.forum_description = 'a simple forum'


u = User.new
u.user_name = 'skyover'
u.user_emoticion = '/face/1.gif'
u.save
这样多烦啊,有没有什么好办法去改变得变得自然一些呢?


前面一个问题好解决,Rails本身就有支持:

1. 在environment.rb里加上这一句就行了。

CODE:

ActiveRecord::Base::table_name_prefix = 'bbs_'2. 不太好处理,Rails里本身没有提供这样的参数用来配置,只有以表名为前缀为字段前缀的才可以处理。没有办法只好自己动手了。

写一个module.

my_base.rb

CODE:

module MyBase   
  def method_missing(method_id, *arguments)
      @prefix ||= self.class.table_name.split(/_/)[1].singularize + '_'
      method_name = method_id.to_s
      method_name =  @prefix + method_name unless method_name.include?(@prefix)
      #puts method_name
      return super(method_name.to_sym, *arguments) if self.respond_to?(method_name.to_sym)     
      raise NoMethodError
  end
end
这个module重载了method_missing的方法,在发现方法不存在的时候就尝试使用表名去掉前缀后的单数形式加上原有的方法名称去匹配,如果还是没有找到,则返回一个没有找到方法的错误信息。

有了这个module,我们就比较好办了,分两种情况处理:
a. 字段名前缀与表名有共通之处的。

CODE:

class Forum < ActiveRecord::Base
  include MyBase
  has_many :topics

  def self.primary_key
    "forum_id"
  end
end
首先,我们include了MyBase这个module,这样这个method_missing方法将mixin到类里。注意primary_key这个方法,因为rails默认的主銉是id,所以我们必须要覆盖这个方法来返回正确的主键名称。

b. 字段名前缀与表名不直接对应的,例如表名叫bbs_categories,字段名为cat_name.

CODE:

class Category < ActiveRecord::Base
  include MyBase
  has_many :forums, :foreign_key => :cat_id
  
  def method_missing(method_id, *arguments)
      @prefix = 'cat_'
      super
  end
  
  def self.primary_key
    "cat_id"
  end
end
我们在这里再次重写父module里的metod_missing方法,手工将@prefix实例变量设置好,这样就处理清楚了。

综上所述,动动脑筋,还是有很多办法还实现自己的想法的。

一点点编写代码过程中的小tips,谨与大家共享。

TAG: rails ruby 元编程 method_missing

小飞猪之Ruby窝 drive2me 发布于2007-08-26 07:26:01
加入收藏了,哈,来自实践的技巧最有价值...
caicai89的菜园子 caicai89 发布于2007-08-27 17:39:44
哦!真聪明!
我也有那样的表,恩,收藏,以备后用
ronzheng发布于2008-04-20 10:37:12
太强了!!!
我来说两句

(可选)

Open Toolbar