如何将关系计数过滤的结果返回到RAILS中的视图?

基本上,我在我的模型上定义了一个属性,它根据另一个表中的值返回true或false。

我想要的是让控制器中的索引操作只返回满足此条件的结果。

我试过这个:

#What I've tried on my Controller: def index @projects = Project.where(:is_available?) end #What I've on my Controller: def index @projects = Project.all end #What I've on my Model: def is_available? workers.count<2 ? true : false end 

谢谢。

为什么你的代码不起作用?

 Project.where(:is_available?) 

在where方法中,您必须传递参数哈希或一串(SQL)条件。 你在这里要做的是选择方法is_available的所有项目? 返回true。 问题是方法is_available? 是一个Ruby方法(在您的模型中定义)。 由于它是一个Ruby函数,因此无法在SQL中调用它。 where方法期望SQL条件,而不是ruby代码。

(感谢@benzado的评论)


要解决您的问题:

这是您正在寻找的,仅在数据库级别计算:

 Project.joins(:workers) .select('projects.*') .group('projects.id') .having('COUNT(workers.*) > 2') 

这应该返回至少有2个与之关联的工人的所有项目。


如何改善这个?

您可以创建此查询的范围 ,以便在任何地方轻松使用它:

 #in your model class Project < ActiveRecord::Base scope :having_more_than_x_workers, lambda do |workers_count| joins(:workers).select('projects.*').group('projects.id').having("COUNT(workers.*) > #{workers_count || 0}") end end 

要在控制器中使用它,例如:

 #in your controller def index @projects = Project.having_more_than_x_workers(2) end 

Rails查询方法(如何)通过创建数据库查询来工作; 换句话说,除非数据模型中实际存在属性where否则不能在where使用属性。 否则,数据库不知道它,也无法为您执行过滤。

在您的情况下,您应该在Project类上定义一个执行“is available?”的方法。 查询,因此您可以使用您的方法代替where 。 你可以这样做:

 class Project < ActiveRecord::Base def self.available_projects where('workers_count > 2') end end 

有关如何编写查询或如何将其定义为命名范围的详细信息,请参阅MrYoshiji的答案 。