我们都知道ActiveRecod借助Arel管理Sql的生成,而Arel使用ast和visitor pattern生成Sql。但是当你想看这颗语法树时,可能会很郁闷:

2.1.5 :047 > pp Post.all.ast
#<Arel::Nodes::SelectStatement:0x007fe6e1406c10
 @cores=
  [#<Arel::Nodes::SelectCore:0x007fe6e1406be8
    @groups=[],
    @having=nil,
    @projections=
     [#<struct Arel::Attributes::Attribute
       relation=
        #<Arel::Table:0x007fe6e2977608
         @aliases=[],
         @columns=nil,
         @engine=
          Post(id: integer, title: string, context: text, created_at: datetime, updated_at: datetime),
  ...

最近我找到一个方法能让你直观的看到这颗语法树的结构。

准备

安装 Graphviz

graphviz和它提供的dot语言是一套绘图DSL,但对这个一无所知并不妨碍阅读这篇文章。

  brew install graphviz

to_dot

对ActiveRecod::Relation调用to_dot,获得生成的dot脚本

2.1.5 :048 > Post.all.to_dot
=> "digraph \"Arel\" {\nnode [width=0.375,height=0.25,shape=record];
70314799067660 [label=\"<f0>Arel::Nodes::SelectStatement\"];\n70314799067500
[label=\"<f0>Array\"];\n70314799067640 [label=\"<f0>Arel::Nodes::SelectCore\"];\n70314799067620
[label=\"<f0>Arel::Nodes::JoinSource\"];\n70314810391300 [label=\"<f0>Arel::Table\"];\n70314810391580
...

生产dot文件

  File.write("post.dot", Post.all.to_dot)

使用graphviz绘图

  $ dot post.dot -T png -o post.png

最后得到的,就是Post.all在arel中所生成的AST。

Updated: