Reputation: 2399
I have this scope in a model called activity
:
scope :today, where("DATE(qualify_date) = ?", Date.today)
and I have another separate model (user
) that will use that to calculate some figures and I want to be able to use:
User.calls_for :today
that will then call theactivity
model and the today
scope but I can't figure out out to use the symbol provided to call that scope
The calls_for
method will contain the following:
activities.*scope*.to_a.sum(&:calls).to_i
Upvotes: 1
Views: 207
Reputation: 14038
Do activities belong to a user? If so you can just call it directly:
@user.activities.today
Keep in mind that your scope needs to be a lambda so that it reevaluates each request, or it will cache the date at which it was first called.
# Ruby 1.8
scope :today, lambda { where("DATE(qualify_date) = ?", Date.today) }
# Ruby 1.9+
scope :today, -> { where("DATE(qualify_date) = ?", Date.today) }
Upvotes: 1
Reputation: 3388
As already stated, #send
is what you'll want to use. But you may want to consider using some meta programming...I'm guessing that besides the :today
scope, you also have something like :yesterday
, :two_weeks_ago
, etc. scopes.
So, you can always do something like:
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
Upvotes: 1
Reputation: 2742
You are going to want to use the send method, I also believe your call to #to_a is unnecessary since activities should return an ActiveRelation which is enumerable.
def calls_for scope = :today
activities.send(scope).sum(&:calls).to_i
end
In the above method you can just call User.calls_for which will be the same as User.calls_for(:today). This will be pretty flexible for the future as you can now define multiple scopes and use the same method. i.e. calls_for(:yesterday)
Also define your scope as Matt has shown above so you don't run into the classic gotcha.
Upvotes: 5
Reputation: 106802
I am a little bit confused if you want to get activities for a special user or a list of all activities. If you want a to call it like this User.call_for(:today)
:
def self.calls_for(date)
Activity.call(date)
end
If you want user.call_for(:today)
:
def calls_for(date)
activities.call(date)
end
But is you see it would be easier just to write Activity.today
or user.activites.today
.
Upvotes: 0