Reputation: 3888
I have a class that contains this class method:
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
And I also have, in the same class, an instance method:
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
I'm getting an 'undefined method' error for #format_date
. (I tried it without the self
in front, at first). Can you not use instance methods in class methods of the same class?
Upvotes: 18
Views: 25577
Reputation: 5437
Just create class method
def self.format_date (..)
...
end
And if u need instance method, delegate it to class method
def format_date *args
self.class.format_date *args
end
And i don't think that it is good idea to call instance methods from class scope
Upvotes: 6
Reputation: 2416
You could do YourClassName.new.format_date(your_date)
, although I think it's pretty clear you should be restructuring your code - this method probably doesn't belong on an instance. Why don't you extend the Date Class, or make format_date
a class method on the class you are using?
EDIT: Here are a few other things to think about with your code:
format_date
method goes to a lot of lengths to manipulate dates as strings. Why not use Ruby's Date Class? Using Date.parse
or Date.strptime
or even "01/01/2001".to_date
might be useful depending on your localeConsider extending the String class for your method, if you really need to make your own method:
class String
def to_friendly_formatted_date
Date.strptime(self, "%d/%m/%y")
end
end
"01/08/09".to_friendly_formated_date
Your class method is crying our for the find_or_initialize_by
helper methods:
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
By god it's long, but it achieves what you're trying to do more elegantly (although I'm open to argument!)
Upvotes: 3
Reputation: 1096
Short answer is no, you cannot use instance methods of a class inside a class method unless you have something like:
class A
def instance_method
# do stuff
end
def self.class_method
a = A.new
a.instance_method
end
end
But as far as I can see, format_date
does not have to be an instance method. So
write format_date like
def self.format_date(date)
# do stuff
end
Upvotes: 31