class GenerateWeatherArtJob < ApplicationJob queue_as :default def perform(city_id) @city = City.find(city_id) weather_data = fetch_weather_data return unless weather_data prompt = generate_prompt(weather_data) return unless prompt image_url = generate_image(prompt) return unless image_url create_weather_art(weather_data, prompt, image_url) rescue StandardError => e Rails.logger.error "Error generating weather art for city #{city_id}: #{e.message}" Rails.logger.error e.backtrace.join("\n") end private attr_reader :city def fetch_weather_data WeatherService.new.get_weather(city.latitude, city.longitude) end def generate_prompt(weather_data) AiService.new.generate_prompt(city, weather_data) end def generate_image(prompt) AiService.new.generate_image(prompt) end def create_weather_art(weather_data, prompt, image_url) tempfile = nil ActiveRecord::Base.transaction do weather_art = city.weather_arts.create!( weather_date: Date.today, prompt: prompt, **weather_data ) tempfile = Down.download(image_url) weather_art.image.attach( io: File.open(tempfile.path), filename: generate_filename, content_type: "image/png" ) weather_art end ensure if tempfile tempfile.close tempfile.unlink end end def generate_filename "#{city.country.name}-#{city.name.parameterize}-#{Time.current.strftime('%Y%m%d-%H%M%S')}.png" end end