新手问题 如何重写自动生成的模型关联方法

lilijreey · 2016年10月02日 · 最后由 zhang_soledad 回复于 2016年10月04日 · 2557 次阅读

现在一个 player, has_many books 我需要大量调用 player.books.count 但是每一次都需要 SQL, 我想重写 books 方法,让 Modle 对象 cache books

def books
  @books ||= xxx这里如何调用原有的books方法 
end

我的方案是

@players = Player.includes(:books).all

@players.each do |player|
  player.books.length # not count
end

#1 楼 @flowerwrong 谢过大神,再问你一个更 NB 的问题, 有没有办法在循环 render 的时候 例如 - books.each |b| link_to 'b.name' , b ## 让每次生成的 html 以入栈的顺序插入 (逆序,最后生成的在最前面)

#2 楼 @lilijreey 如果我没有理解错,reverse books 就可以了。

counter_cache 啊

#3 楼 @flowerwrong #4 楼 @Rei 都不是最好的解决方案哦

#5 楼 @lilijreey 为什么 counter_cache 不是最好的解决方案?

#6 楼 @Rei 原来是版主,这个面子还是要给的.不然我以后就不用在 ruby-chain 混了. 个人审美原因.最好是开发这不需要关系什么 cache 的东西.

#7 楼 @lilijreey 你不是在开发自己的 cache 么?

@Rei Counter Cache 并不太可靠,参考我的 PR https://github.com/rails/rails/pull/9236 然而之后 Rails 4 的实现有变动,Shopify 的人接盘后还是坑的状态... https://github.com/rails/rails/pull/14849

不过 Counter Cache 本身也是通过 hook 持久化操作的一系列回调实现的,思路本身没问题,问题在于,框架层面做这事要考虑的因素太多,难以正确实现。 需要 Counter 强一致性的场合自己模仿一下 hook 掉 after save 之类的方法就好了

调用原始实现(这里属于方法的继承)使用 super 就可以了应该。 不过,在任何情况下,覆盖 Rails 动态生成的方法,都是非常非常不明智的。 在你给出的代码段里 books 如果是 Rails 根据关系生成的方法话,你这样去覆写基本可以推断是错误的了

#11 楼 @jasl 是的,counter_cache 只能支持简单情况,然而楼主的例子就是简单情况。

简单情况用 counter_cache 方便,我个人偏向用 DB trigger。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号