覆盖ActiveRecord关系的count()方法可以吗? [英] Is overriding an ActiveRecord relation's count() method okay?

查看:51
本文介绍了覆盖ActiveRecord关系的count()方法可以吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我在Rails应用程序中具有以下关系:

Let's say I have the following relationship in my Rails app:

class Parent < ActiveRecord::Base
  has_many :kids
end

class Kid < ActiveRecord::Base
  belongs_to :parent
end

我希望父母成为能够查看他们的健谈孩子的列表,并使用该计数对列表进行分页。这是一种方法(我知道有点奇怪,请忍受):

I want parents to be able to see a list of their chatty kids, and use the count in paginating through that list. Here's a way to do that (I know it's a little odd, bear with me):

class Parent < ActiveRecord::Base
  has_many :kids do
    def for_chatting
      proxy_association.owner.kids.where(:chatty => true)
    end
  end
end

但是!有些父母有数百万个孩子,即使数据库索引良好, p.kids.for_chatting.count 仍需要花费很长时间才能运行。我很确定这不能直接解决。但!我可以设置 Parent#chatty_kids_count 属性,并使用数据库触发器正确地对其进行更新。然后,我可以:

But! Some parents have millions of kids, and p.kids.for_chatting.count takes too long to run, even with good database indexes. I'm pretty sure this cannot be directly fixed. But! I can set up a Parent#chatty_kids_count attribute and keep it correctly updated with database triggers. Then, I can:

class Parent < ActiveRecord::Base
  has_many :kids do
    def for_chatting
      parent = proxy_association.owner
      kid_assoc = parent.kids.where(:chatty => true)
      def kid_assoc.count
        parent.chatty_kids_count
      end
    end
  end
end

然后 parent.kids.for_chatting.count 使用缓存的计数,我的分页速度很快。

And then parent.kids.for_chatting.count uses the cached count and my pagination is fast.

但是!在单例关联对象上覆盖 count()会使呃,我太聪明了会使我的大脑大面积发光。

But! Overriding count() on singleton association objects makes the uh-oh, I am being way too clever part of my brain light up big-time.

我觉得有一种更清晰的方法来解决这个问题。在那儿?还是这是是的,很奇怪,请评论一下您为什么这样做,这样会很好的情况?

I feel like there's a clearer way to approach this. Is there? Or is this a "yeah it's weird, leave a comment about why you're doing this and it'll be fine" kind of situation?

推荐答案

编辑:



我检查了will_paginate的代码,似乎它没有使用 count 方法AR关系,但我发现您可以为分页提供选项 total_entries

I checked the code of will_paginate, seems like it is not using count method of AR relation, but i found that you can provide option total_entries for paginate

@kids = @parent.kids.for_chatting.paginate(
  page:          params[:page], 
  total_entries: parent.chatty_kids_count
)




这不起作用



您可以使用包装器像这里的收藏
https://github.com/kaminari/kaminari / pull / 818#issuecomment-252788488
只是覆盖计数方法。

This is not working

You can use wrapper for collection like here https://github.com/kaminari/kaminari/pull/818#issuecomment-252788488​, just override count method.

class RelationWrapper < SimpleDelegator
  def initialize(relation, total_count)
    super(relation)
    @total_count = total_count
  end

  def count
    @total_count 
  end
end

# in a controller:
relation = RelationWrapper.new(@parent.kids.for_chatting, parent.chatty_kids_count)


这篇关于覆盖ActiveRecord关系的count()方法可以吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆