在我有限的知识中,我不知道如何在不将志愿者作为状态方法的参数的情况下写出来。这通常不会成为问题,除非我需要所有不规范的志愿者。然后我必须循环遍历Volunteers.all并根据状态方法评估每个。我觉得这里的开销太大了。
Class Volunteer < ActiveRecord::Base
has_many :reports
def status(volunteer)
case
when volunteer.reports.nought.where(:report_month => Report_range.months(6)).count > 5
return 'inactive'
when volunteer.reports.nought.where(:report_month => Report_range.months(6)).count >= 3
return 'irregular'
else
return 'active'
end
end
end
class Report < ActiveRecord::Base
belongs_to :volunteer
scope :nought, -> {where("hours IS NULL") || where("hours: 0")}
end
module Report_range
def self.months(range)
Volunteer.first.reports.order("report_month desc").limit(range).pluck(:report_month)
end
end
提前感谢您帮助一个菜鸟!
答案 0 :(得分:1)
def status(volunteer)
case
when volunteer.reports.nought.where(:report_month => Report_range.months(6)).count > 5
return 'inactive'
when volunteer.reports.nought.where(:report_month => Report_range.months(6)).count >= 3
return 'irregular'
else
return 'active'
end
end
您不需要通过志愿者,因为您在已经可以直接访问报告的志愿者实例上调用方法状态。所以上面变成了:
def status
case
when reports.nought.where(:report_month => Report_range.months(6)).count > 5
return 'inactive'
when reports.nought.where(:report_month => Report_range.months(6)).count >= 3
return 'irregular'
else
return 'active'
end
end
此外,您正在运行两次计数查询,这不是最佳选择。我建议:
def status
number_of_reports = reports.nought.where(:report_month => Report_range.months(6)).count
case
when number_of_reports > 5
return 'inactive'
when number_of_reports >= 3
return 'irregular'
else
return 'active'
end
end
最后,案例会返回匹配值,因此您不需要返回。
def status
number_of_reports = reports.nought.where(:report_month => Report_range.months(6)).count
case
when number_of_reports > 5
'inactive'
when number_of_reports >= 3
'irregular'
else
'active'
end
end
还有更多,但这是一个开始。
答案 1 :(得分:1)
我做这样的事情:
class Volunteer < ActiveRecord::Base
has_many :reports
def status
if number_of_recent_nought_reports > 5
'inactice'
elsif number_of_recent_nought_reports >= 3
'irregular'
else
'active'
end
end
private
def number_of_recent_nought_reports
# You could move the where call to scope in your `Report` class.
@recent_nought_reports ||= reports.nought.where(:report_month => Report_range.months(6)).count
end
end
答案 2 :(得分:1)
您也可以将其指定为使用@ Magnuss&#39;代码作为基点
class Volunteer < ActiveRecord::Base
has_many :reports
STATUSES = {(0..2) => 'active', (3..5) => 'irregular'}
def status
STATUSES.find(->{['inactive']}){|range,_| range === number_of_recent_nought_reports}.pop
end
private
def number_of_recent_nought_reports
# You could move the where call to scope in your `Report` class.
@recent_nought_reports ||= reports.nought.last_n_months(6).count
end
end
class Report < ActiveRecord::Base
belongs_to :volunteer
scope :nought, -> {where("hours IS NULL") || where("hours: 0")}
scope :last_n_months, ->(months){ where(:report_month => Report_range.months(months)) }
end
通过在您认为合适时重新定义STATUSES
,我可以更灵活地添加更多状态。
这样做的第一个结果是number_of_recent_nought_reports
在STATUSES
中定义的范围内,如果它超出任何范围['inactive']
,则返回pop
{ {1}}仅提取状态。
我还将report_month范围移至Report
last_n_months
。
答案 3 :(得分:0)
你可以写:
def status(volunteer)
case volunteer.reports
.nought
.where(:report_month => Report_range.months(6))
.count
when (6..Float::INFINITY) then 'inactive'
when (3..5) then 'irregular'
else 'active'
end