module Liars # 目前实现了has_many和belongs_to关系 # 如假设user和role是一对多的关系 # u = Liars::User.new(:name=>'luoxin') # u.roles << Liars::Role.new(:name=>'admin') # u.save # 则对象已自动建立了关联,以后可以通过u.roles和u.roles[0].user来访问关联对象 # 目前的实现存在着许多bug # 首先,如果是通过给从属对象赋主对象值,保存从属对象时主对象不会有从对象的引用 # 比如role.user = u # 调用role.save时user并不会保存,因此role上保存有user的引用但user上并没有role的引用 # 这里的一个解决方案是判断user是不是新对象,如果是新对象则不保存,如果不是新对象则仅保存关联关系 # 另外,通过user.roles << role加入role时,再调用role.user时并不会马上产生效果,这是因为<<还是常规的数组方法, # 要实现立即的效果应该再定义一个Association类集成至数组但改变了其中很多方法的定义 class M attr_reader :id def initialize(fields={}) fields.each {|k, v| instance_variable_set("@#{k}", v)} end class << self def inherited(child) DbEngine.all_models << child end def fields @fields ||= [:id] end def associations (@associations ||= []) end def fields_and_associations fields + associations.collect {|x| x[1]} end def create(fields={}) self.new(fields).save end def find(ids) DbEngine.find(self, ids) end def has_field(name) attr_accessor name fields << name end def has_many(name) class_name = name.singularize.camelize associations << [:has_many, name] class_eval <<-EOF def #{name} @#{name} ||= [] @#{name}_obj ||= DbEngine.find(#{class_name}, @#{name}) end def #{name}=(value) @#{name}_obj = value end EOF end def belongs_to(name) class_name = name.camelize associations << [:belongs_to, name] class_eval <<-EOF def #{name} @#{name}_obj ||= DbEngine.find(#{class_name}, @#{name}) end def #{name}=(value) @#{name} = value.id @#{name}_obj = value end EOF end end def save DbEngine.save(self) end def new? @id == nil end def data self.class.fields_and_associations.inject({}) {|h, f| h[f] = instance_variable_get("@#{f}"); h} end def destroy DbEngine.delete(self) end end end