让我们说我的Rails应用程序中有以下关系:
class Parent < ActiveRecord::Base
has_many :kids
end
class Kid < ActiveRecord::Base
belongs_to :parent
end
我希望父母能够看到他们健谈的孩子的列表,并通过该列表分页使用计数。这是一种方法(我知道它有点奇怪,忍受我):
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
属性并使用数据库触发器正确更新它。然后,我可以:
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
使用缓存的计数,我的分页速度很快。
但是!在单例关联对象上覆盖count()
使得呃 - 哦,我太聪明了我大脑的一部分亮起了很长时间。
我觉得有更清晰的方法来解决这个问题。在那儿?或者这是一个&#34;是的,它是奇怪的,留下评论为什么你这样做,它会很好&#34;那种情况?
答案 0 :(得分:0)
我检查了will_paginate的代码,好像它没有使用AR关系的count
方法,但我发现你可以为paginate提供选项total_entries
@kids = @parent.kids.for_chatting.paginate(
page: params[:page],
total_entries: parent.chatty_kids_count
)
这不起作用
您可以像这里一样使用包装器进行收集 https://github.com/kaminari/kaminari/pull/818#issuecomment-252788488, 只是覆盖计数方法。
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)