由关联计数组成的 Rails 查询,最好使用范围
Posted
技术标签:
【中文标题】由关联计数组成的 Rails 查询,最好使用范围【英文标题】:Rails queries that consist of counts on associations, preferably with scopes 【发布时间】:2013-07-02 13:25:40 【问题描述】:我一直在为我的服务制作一个搜索页面,它包含几个基于关联的搜索参数,我可以想到一些凌乱的长 sql 混乱,但更喜欢一些更简洁的方法,作为示例,
class Person < ActiveRecord::Base
has_many :friends
end
Friend 有一个表示友谊状态的属性,比如friend_type
class Friend < ActiveRecord::Base
belongs_to :person
end
搜索表单将包含许多参数,其中两个用于搜索拥有超过一定数量朋友的人,以及有多少人的朋友的朋友类型设置为“bff”。
我想做的是在模型中有一些作用域方法,并且在Controller中能够做到这一点,
Person 中的一些模型范围是这样的,
scope :by_friends_count_greater_than, lambda |value| joins(:friends).where( #count friends#, value ) if value
scope :by_bff_count_greater_than, lambda |value| joins(:friends).where( ##count friends with bff status## , value ) if value
并在控制器中调用它们,
@people = Person.by_friends_count_greater_than(params[:query][:friends_count])
.by_bff_count_greater_than(params[:query][:bff_count])
我一直在尝试 squeel,这似乎是一个非常好的资产,考虑到它可以调用查询中的方法。是否可以以这种方式完成搜索查询?
如果有更好的方法来解决这个问题,将不胜感激。
【问题讨论】:
【参考方案1】:您可能对 counter_cache 感兴趣以进行更简单的查询。
它会自动为每个 Person 模型增加一个计数器。
http://railscasts.com/episodes/23-counter-cache-column
你必须在你的 Person 模型中添加一个 friends_count 列
并在belongs_to上指定counter_cache
class Friend < ActiveRecord::Base
belongs_to :person, counter_cache: true
end
【讨论】:
这是我没有想过的方法,谢谢你的建议。如果我正确理解计数器缓存,它将适用于普通朋友的计数,但它不适用于计算具有特定属性的朋友。 不,但是计数器缓存的工作方式也可以手工制作以实现高效查询。如果需要以上是关于由关联计数组成的 Rails 查询,最好使用范围的主要内容,如果未能解决你的问题,请参考以下文章