如何将关系计数过滤的结果返回到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的答案 。