我在名为activity
的模型中有这个范围:
scope :today, where("DATE(qualify_date) = ?", Date.today)
我还有另一个单独的模型(user
),它将使用它来计算一些数字,我希望能够使用:
User.calls_for :today
然后会调用activity
模型和today
范围,但我无法弄清楚是否使用提供的符号来调用该范围
calls_for
方法将包含以下内容:
activities.*scope*.to_a.sum(&:calls).to_i
答案 0 :(得分:5)
您将要使用send方法,我也相信您对#to_a的调用是不必要的,因为活动应返回可枚举的ActiveRelation。
def calls_for scope = :today
activities.send(scope).sum(&:calls).to_i
end
在上面的方法中,您只需调用User.calls_for,它与User.calls_for(:today)相同。这对未来非常灵活,因为您现在可以定义多个范围并使用相同的方法。即calls_for(:昨天)
还可以像Matt上面所示定义你的范围,这样你就不会遇到经典的问题。
答案 1 :(得分:1)
活动属于用户吗?如果是这样,你可以直接调用它:
@user.activities.today
请记住,您的范围必须是lambda,以便重新评估每个请求,或者它将缓存首次调用它的日期。
# Ruby 1.8
scope :today, lambda { where("DATE(qualify_date) = ?", Date.today) }
# Ruby 1.9+
scope :today, -> { where("DATE(qualify_date) = ?", Date.today) }
答案 2 :(得分:1)
如前所述,#send
是你想要使用的。但是你可能想考虑使用一些元编程......我猜测除了:today
范围之外,你还有:yesterday
,:two_weeks_ago
等范围。
所以,你总是可以这样做:
def calls_for(foo)
activities.send(foo).sum(:calls).to_i
end
def method_missing(foo, *args, &block)
if foomatch = foo.to_s.match(/^calls_for_(\w+)/)
foo_scope = foomatch[1].to_s
send(:calls_for, foo_scope)
else
super
end
end
def respond_to?(meth, x=false)
if meth.match(/^calls_for_(\w+)/)
true
else
super
end
end
答案 3 :(得分:0)
如果您想获得特殊用户的活动或所有活动的列表,我会有点困惑。如果您想要像User.call_for(:today)
一样调用它:
def self.calls_for(date)
Activity.call(date)
end
如果您需要user.call_for(:today)
:
def calls_for(date)
activities.call(date)
end
但是你看到写Activity.today
或user.activites.today
会更容易。