14

我有一个包含此类方法的类:

def self.get_event_record(row, participant)
  event = Event.where(
      :participant_id   => participant.id,
      :event_type_code  => row[:event_type],
      :event_start_date => self.format_date(row[:event_start_date])
  ).first

  event = Event.new(
      :participant_id   => participant.id,
      :event_type_code  => row[:event_type],
      :event_start_date => self.format_date(row[:event_start_date])
  ) if event.blank?

  event
end

在同一个类中,我还有一个实例方法:

def format_date(date)
  parsed_date = date.split('/')

  # if month or day are single digit, make them double digit with a leading zero
  if parsed_date[0].split("").size == 1
    parsed_date[0].insert(0, '0')
  end
  if parsed_date[1].split("").size == 1
    parsed_date[1].insert(0, '0')
  end

  parsed_date[2].insert(0, '20')

  formatted_date = parsed_date.rotate(-1).join("-")
  formatted_date
end

我收到一个“未定义的方法”错误#format_date。(起初我尝试过没有self前面的)。不能在同一个类的类方法中使用实例方法吗?

4

3 回答 3

28

简短的回答是否定的,除非你有类似的东西,否则你不能在类方法中使用类的实例方法:

class A
  def instance_method
    # do stuff
  end

  def self.class_method
     a = A.new
     a.instance_method
  end
end

但据我所知,format_date不一定是实例方法。所以写 format_date 像

def self.format_date(date)
   # do stuff
end
于 2012-06-28T13:08:04.330 回答
7

只需创建类方法

def self.format_date (..)
  ...
end

如果您需要实例方法,请将其委托给类方法

def format_date *args
  self.class.format_date *args
end

而且我认为从类范围调用实例方法不是一个好主意

于 2012-06-28T13:07:49.053 回答
3

你可以这样做YourClassName.new.format_date(your_date),虽然我认为很明显你应该重组你的代码——这个方法可能不属于一个实例。你为什么不扩展日期类,或者format_date在你正在使用的类上创建一个类方法?

编辑:这里有一些其他的事情要考虑你的代码:

  • 您的整个format_date方法花费了很多时间来将日期作为字符串进行操作。为什么不使用 Ruby 的日期类?根据您的语言环境,使用Date.parseDate.strptime什至"01/01/2001".to_date可能有用
  • 如果您确实需要创建自己的方法,请考虑为您的方法扩展 String 类:

    class String
      def to_friendly_formatted_date
        Date.strptime(self, "%d/%m/%y")
      end
    end
    "01/08/09".to_friendly_formated_date
    
  • find_or_initialize_by您的类方法正在为我们的辅助方法哭泣:

    self.get_event_record(row, participant)
      find_or_initialize_by_participant_id_and_event_type_code_and_event_start_date(:participant_id => participant.id, :event_type_code => row[:event_type_code], :event_start_date => row[:event_start_date].to_friendly_formatted_date)
    end
    

天哪,它很长,但它更优雅地实现了你想要做的事情(尽管我愿意争论!)

于 2012-06-28T13:06:12.183 回答