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

lilijreey · 发布于 2016年10月02日 · 最后由 zhang_soledad 回复于 2016年10月04日 · 798 次阅读
24996

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

def books
  @books ||= xxx这里如何调用原有的books方法 
end
共收到 14 条回复
9442

我的方案是

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

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

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

9442

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

1

counter_cache 啊

24996

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

1

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

24996

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

1

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

8744

prepend

1107

@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之类的方法就好了

1107

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

1

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

5178

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

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