美文网首页
Rails中的has_many的运行流程是怎样的

Rails中的has_many的运行流程是怎样的

作者: 33d8e4ec2cc9 | 来源:发表于2017-03-08 13:53 被阅读238次

    可参考https://ruby-china.org/topics/32419

    屏幕快照 2017-03-08 下午1.29.34.png

    整个方法就两行,几乎全部写在了Builder::HasMany这个类里面,继续点进去看

    屏幕快照 2017-03-08 下午1.31.14.png

    从这个方法来看,流程大致为创建reflection实例 -> 创建accessors方法 -> 创建回调方法 -> 创建验证方法 -> 创建扩展方法 -> 返回reflection实例
    reflection实例用来干嘛?等会回来说

    屏幕快照 2017-03-08 下午1.36.03.png

    最主要的方法都在这里了

    generated_association_methods这个方法要重点讲一讲

    屏幕快照 2017-03-08 下午1.37.48.png

    这个地方非常酷,方法并不是直接定义在本身的class中,而是创建一个常量到一个新module,然后include
    ruby有个特性,就是你include module进来的时候,会复制一个Rclass结构体,但是它的方法表是指向原Rclass结构体的

    所以你先include一个module进来,然后再改动这个module的方法,你的执行include的这个class也可以调用新生成的方法
    这就是为什么可以先生成一个空的module,include进来以后再define属于这个module的方法
    这样做可以让你自己在model定义同名方法,并使用default_scope调用原方法。

    define_readers和define_writers分别创建读和写,但是这边我很奇怪,我传进来的参数去哪了,options并没有用在这两个方法里,于是我找到association这个方法

    屏幕快照 2017-03-08 下午1.45.05.png

    self.class._reflect_on_association(name)
    这个就是比较厉害的地方了,从哪里取?回到一开始

    Reflection.add_reflection self, name, reflection

    真相大白了,reflection实例始终被保存在ActiveRecord::Reflection里面,也就是说我们使用has_many的时候,实际上是创建了Reflection实例,这个实例里面是我们传到has_many里面的参数,调用的时候吧实例丢过去当参数,当我们调用到方法的时候,实际上是先找到Reflection实例,再用这个实例做一系列的事情

    屏幕快照 2017-03-08 下午1.50.47.png

    相关文章

      网友评论

          本文标题:Rails中的has_many的运行流程是怎样的

          本文链接:https://www.haomeiwen.com/subject/ztebgttx.html