再谈Bullet

曾几何时,开发环境中突如其来的Bullet(以下简称bt)搞得我措手不及,无尽的弹框弄得人心烦意乱;曾几何时,不明白什么N+1 Query的我,对着弹框里的提示信息,无脑地到处乱加includes。。。

时过境迁。。。好吧,我不文艺了,讲主题吧!

前两天想抽出点时间对快轮系统的性能进行一些优化,首先想到的就是bt这个gem,由于该项目还未配置过bt,因此尝试着安装一下

1.安装

在gemfile的开发组中加入了bt

group :development do
  gem "bullet"
end

然后bundle了一下,重启服务,发现并没有什么X用。。。

2.配置

于是赶紧在github里查了一下,原来是需要在 config/environments/development中配置的

if defined?(Bullet)  
  config.after_initialize do
    Bullet.enable = true
    Bullet.alert = true
    Bullet.bullet_logger = true
    Bullet.console = true
    Bullet.growl = false
    # Bullet.xmpp = { :account  => '[email protected]',    
    #                 :password => 'bullets_password_for_jabber',    
    #                 :receiver => '[email protected]',    
    #                 :show_online_status => true }    Bullet.rails_logger = true    
    # Bullet.honeybadger = true    # Bullet.bugsnag = true    
    # Bullet.airbrake = true    # Bullet.rollbar = true    Bullet.add_footer = true    
    # Bullet.stacktrace_includes = [ 'your_gem', 'your_middleware' ]    
    # Bullet.slack = { webhook_url: 'http://some.slack.url', foo: 'bar' }    
  end
end

需要增加一个是否安装bt的判断,然后配置信息中,首先需要enable,然后alert就是弹框提示,bullte_logger就是在log中也显示提示信息;

此时再重启一下服务,果然熟悉的弹框出现了!

3.多重includes

解决普通的N+1 Query大家已经比较熟悉了,此处也不多赘述。有时候会出现includes之后,依然提示还是N+1的情况,仔细分析一下,原来被includes的对象,还会继续调用与自己关联的其他模型,此时就需要多重includes。解决思路有了,剩下的其实也就是个写法问题:

# 比如在‘任务动态’页面,每个event都需要调用对应的eventable(因为是多态关联,其实就是task或者subtask)
# 并且还会调用操作人(operator)的信息,比如username
# 此时如果仅仅includes这两个,还是会继续提示N+1 Query
Fg::Event.includes([:eventable, :operator])
# 原来是因为任务动态页面还会显示操作人的头像,而头像的链接不是存在users表中,而是存在employees表中,两张表是一对一的关系,这时就需要多重includes了:
Fg::Event.includes([:eventable, :operator => [:employee]])
# 理论上可以includs无数层,有一点需要注意,需要重复includes应该写在后面,不然会报错,比如:
Fg::Event.includes([:operator => [:employee], :eventable])
4.Counter Cache

当出现这个提示的时候,我又懵了。。。
然后在railscast找了个视频教程,其中正好有说明这个问题的内容。
举个例子:

# 有一张provinces表,和一张cities表,显然,一个province has_many cities
# 然后我在一个页面,列出所有的province的名称,并且在名称后面显示每个province具有的city数量:province_a.cities.count
# 此时刷新一下页面,就跳出提示说counter_cache了
# 解决方案如下:
# 1.给provinces表加一个cities_count的字段,整数型,默认值是0,执行迁移;
# 2.在cities表申明belongs_to province的地方,多加上一句话:
    belongs_to :province, counter_cache: true
# 3.在需要调用的地方,直接调用 province_a.cities_count

# 其实这么申明之后,本质就是,当cities表的数据有添加或者删除时,会自动找到对应的province,然后更新其cities_count字段(加一或者减一)

你可能感兴趣的:(再谈Bullet)