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

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

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

def books
  @books ||= xxx这里如何调用原有的books方法 
end
共收到 14 条回复
9442
flowerwrong · #1 · 2016年10月02日

我的方案是

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

@players.each do |player|
  player.books.length # not count
end
24996
lilijreey · #2 · 2016年10月02日

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

9442
flowerwrong · #3 · 2016年10月02日

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

1
Rei · #4 · 2016年10月02日 1 个赞

counter_cache 啊

24996
lilijreey · #5 · 2016年10月02日

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

1
Rei · #6 · 2016年10月02日

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

24996
lilijreey · #7 · 2016年10月02日

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

1
Rei · #8 · 2016年10月02日

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

24996
lilijreey · #9 · 2016年10月02日

#8楼 @Rei 我错了😁

8744
lithium4010 · #10 · 2016年10月03日

prepend

1107
jasl · #11 · 2016年10月04日

@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
jasl · #12 · 2016年10月04日

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

1
Rei · #13 · 2016年10月04日

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

5178
zhang_soledad · #14 · 2016年10月04日

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

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