Это должно быть решено с использованием шаблона стратегии.Для каждого возможного трекера (DHL, UPS, ...), который будет обрабатывать создание и обновление соответствующим образом.
Так что это будет выглядеть примерно так:
class Number
def track
tracker = get_tracker(tracking)
tracker.create_tracking(self)
save
end
def update_number
tracker = get_tracker(tracking)
tracker.update_tracking(self)
save
end
def get_tracker(tracking)
tracking_number = sanitize(tracking)
case determine_type(tracking_number)
when 'UPS'
UPSTracker.new(tracking_number)
when 'DHL'
DHLTracker.new(tracking_number)
end
end
end
class UPSTracker
def initialize(tracking_number)
@tracking_number = tracking_number
end
def create_tracking(number)
tracker = ups.track(:tracking_number => number)
update_number_properties(number, tracking)
# store events
tracker.events.each do |event|
create_new_event(event)
end
end
def update_tracking(number)
tracker = ups.track(:tracking_number => number)
update_number_properties(number, tracking)
last_event = self.events.ordered.first.occured_at
tracker.events.each do |event|
if last_event and (event.occurred_at > last_event)
create_new_event(event)
end
end
end
protected
def update_number_properties
number.carrier = Carrier.where(:name => 'UPS').first
number.service = tracker.service_type
number.destination_country = tracker.destination_country
number.destination_state = tracker.destination_state
number.destination_city = tracker.destination_city
number.origin_country = tracker.origin_country
number.origin_state = tracker.origin_state
number.origin_city = tracker.origin_city
number.signature = tracker.signature_name
number.scheduled_delivery = tracker.scheduled_delivery_date
number.weight = tracker.weight
end
def create_new_event
new_event = Event.new
new_event.number = self
new_event.city = event.city
new_event.state = event.state
new_event.postalcode = event.postal_code if event.postal_code
new_event.country = event.country
new_event.status = event.name
new_event.status_code = event.type
new_event.occured_at = event.occurred_at
new_event.save
end
end
Этот код может быть улучшенЯ предполагаю, что создание событий и трекинг будет распространяться на разных носителях.Так что общий базовый класс может быть.Во-вторых, в двух методах внутри Number
мы вызываем get_tracker
: вероятно, этот трекер может быть выбран по времени создания (экземпляра Number
) и должен быть выбран один раз и сохранен в переменной экземпляра.
Кроме того, я хотел бы добавить, что имена должны быть значимыми, поэтому класс Number
не кажется мне достаточно значимым.Имя должно выражать намерение и предпочтительно совпадать с именами и понятиями из вашей проблемной области.