简体   繁体   中英

ruby class as a parameter in a method

I have this class in a ruby on rails application

class ChartData
  def self.user_logs_by_day(logs)
    days_with_hours = Hash.new{|h, k| h[k] = Hash.new(&h.default_proc)}
      logs.each do |log|
        days_with_hours[log.user.name][log.log_date] = log.total_hours
      end
    days_with_hours
  end

  def self.project_logs_by_day(logs)
    days_with_hours = Hash.new{|h, k| h[k] = Hash.new(&h.default_proc)}
      logs.each do |log|
        if !log.project.nil?
          days_with_hours[log.project.name][log.log_date] = log.total_hours
        else
          days_with_hours[@default][log.log_date] = log.total_hours
        end
      end
    days_with_hours
  end
end

I want to make the two methods into one like this, because I want to use this method for many models.

class ChartData
  def self.logs_by_day(logs, klass)
    days_with_hours = Hash.new{|h, k| h[k] = Hash.new(&h.default_proc)}
      logs.each do |log|
        if !log.klass.nil?
          days_with_hours[log.klass.name][log.log_date] = log.total_hours
        else
          days_with_hours[@default][log.log_date] = log.total_hours
        end
      end
    days_with_hours
  end
end

I want to pass the class or model into the method like this

ChartData.logs_by_day(logs, Project)

How can I handle the parameter Project in the model so it gets to be a instance method on the log?

A rather clumsy attempt

1.9.3p125 :026 > Project.name.downcase
 => "project" 

Any better? Other refactor suggestions are welcome

Why do you want to pass the class? You're not using it anywhere. Pass a symbol.

ChartData.logs_by_day(logs, :project)

and then

def self.logs_by_day(logs, prop)
  # ...
  log.send(prop).name
  # ...
end

For Rails, what you probably want is something like klass.name.underscore . This and its counterpart camelize are designed to convert between method-style naming conventions and module-style naming conventions. In particular, this will work with class names like "UserData", which should be "user_data" rather than the "userdata" you'd get from just downcasing. You can then pass it as the method selector to send .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM