问题
Seems like there should be a good way via MP to DRY this up:
class Dashboard
def self.num_registrations_past_day
return User.recent_registrations(24.hours.ago).count
end
def self.num_registrations_past_three_days
return User.recent_registrations(3.days.ago).count
end
def self.num_registrations_past_seven_days
return User.recent_registrations(7.days.ago).count
end
def self.num_registrations_past_month
return User.recent_registrations(30.days.ago).count
end
def self.avg_registrations_past_three_days
return (self.num_registrations_past_three_days / 3.to_f)
end
def self.avg_registrations_past_seven_days
return (self.num_registrations_past_seven_days / 7.to_f)
end
def self.avg_registrations_past_month
return (self.num_registrations_past_month / 30.to_f)
end
def self.total_registered_users
return User.count
end
def self.total_activated_users
return User.total_activated
end
end
回答1:
I would just have the length of time passed in as an argument:
def self.num_registrations_since(time)
User.recent_registrations(time).count
end
def self.avg_registrations_since(time)
self.num_registrations_since(time) / ((Time.now - time) / 1.day)
end
See, it's still very readable:
Dashboard.num_registrations_since(3.days.ago)
Dashboard.avg_registrations_since(7.days.ago)
For fun, here is the metaprogramming way:
{ :day => 24.hours.ago,
:three_days => 3.days.ago,
:seven_days => 7.days.ago,
:month => 30.days.ago }.each do |method_suffix, time|
define_singleton_method "num_registrations_past_#{method_suffix}" do
User.recent_registrations(time).count
end
define_singleton_method "avg_registrations_past_#{method_suffix}" do
self.send("num_registrations_past_#{method_suffix}") / ((Time.now - time) / 1.day)
end
end
回答2:
If you are set on using those functions names I would do this:
class Dashboard def self.num_registrations_past_day return User.recent_registrations(24.hours.ago).count end [['three_days', 3], ['seven_days', 7], ['month', 30]].each do |name, days| class_eval <<-EVAL def self.num_registrations_past_#{name} User.recent_registrations(#{days}.days.ago).count end def self.avg_registrations_past_#{name} self.num_registrations_past_#{name} / #{days}.to_f end EVAL end def self.total_registered_users return User.count end def self.total_activated_users return User.total_activated end end
来源:https://stackoverflow.com/questions/4858668/how-to-dry-using-metaprogramming