Не делайте HTTP-звонки в вашей модели. Даже без какого-либо кода ваша модель уже имеет массу обязанностей, которые она получает от ActiveRecord::Base
:
- проверок
- ассоциаций
- постоянство
- обратные вызовы
- naming
- i18n
Вместо этого создайте отдельный клиентский объект, который извлекает данные из API. Это дает вам объект, который выполняет только одну работу, которую легко протестировать и заглушить:
# app/clients/rest_countries_client.rb
# HTTP client for the restcountries.eu API
class RestCountriesClient
include HTTParty
base_uri 'restcountries.eu/rest/v2'
format :json # this will automatically parse the response
def self.region(region)
get("/region/#{region}")
end
end
Это позволяет просто протестировать вызов API из консоли, вызвав RestCountriesClient.region('africa')
, и вы можете увидеть возвращено га sh без каких-либо побочных эффектов.
Для фактического выполнения вызова и сохранения объектов, которые вы хотите использовать в качестве служебного объекта или ActiveJob :
# app/jobs/country_importer_job.rb
# Persists countries from the restcountries.eu API
class CountryImporterJob < ApplicationJob
def perform(region = 'africa')
response = RestCountriesClient.region(region)
return unless response.success?
response.map do |line|
Country.create(name: line["name"])
end.select(&:persisted?)
end
end
Затем вы вызываете эту работу из контроллера:
CountryImporterJob.perform_now('africa')