考虑一个简单的关联……
class Person
has_many :friends
end
class Friend
belongs_to :person
end
让所有在rel和/或meta_where中没有朋友的人获得朋友的最干净的方法是什么?
然后是has_many:through version
class Person
has_many :contacts
has_many :friends, :through => :contacts, :uniq => true
end
class Friend
has_many :contacts
has_many :people, :through => :contacts, :uniq => true
end
class Contact
belongs_to :friend
belongs_to :person
end
我真的不想使用counter_cache -据我所读到的,它不能与has_many:through一起工作
我不想拉出所有的person.friends记录并在Ruby中循环它们-我想要有一个可以与meta_search gem一起使用的查询/范围
我不介意查询的性能成本
而且离实际的SQL越远越好……
没有朋友的人
Person.includes(:friends).where("friends.person_id IS NULL")
或者至少有一个朋友
Person.includes(:friends).where("friends.person_id IS NOT NULL")
你可以通过在Friend上设置作用域来实现这一点
class Friend
belongs_to :person
scope :to_somebody, ->{ where arel_table[:person_id].not_eq(nil) }
scope :to_nobody, ->{ where arel_table[:person_id].eq(nil) }
end
还有至少有一个朋友的人:
Person.includes(:friends).merge(Friend.to_somebody)
没有朋友的:
Person.includes(:friends).merge(Friend.to_nobody)
不幸的是,你可能正在寻找一个涉及SQL的解决方案,但你可以在一个范围内设置它,然后只使用该范围:
class Person
has_many :contacts
has_many :friends, :through => :contacts, :uniq => true
scope :without_friends, where("(select count(*) from contacts where person_id=people.id) = 0")
end
要得到它们,你可以用Person。without_friends.order("name").limit(10)