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.parseもありDate.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 に答える