Хорошее решение для этого, как правило, связаны с использованием работника. Все, что не является критически важным для запроса и которое связано с сложными вычислениями, может быть отложено и запущено позже фоновым заданием.
Две общие реализации рабочих: delayed_job и resque.
Например, с Resque, вы бы иметь класс работу в app/jobs/impression_creation_job.rb
, содержащий что-то вроде этого:
class ImpressionJob
@queue = :impression
def self.perform(attrs)
Impression.create!(attrs)
end
end
И вы можете вызвать его в контроллере, как что:
after_filter :save_impression
private
def save_impression
Resque.enqueue(ImpressionJob, ip_address: request.remote_ip, controller_name: params[:controller], action_name: params[:action], referer: request.referer)
end
Этом обеспечит быструю обработку на стороне запроса (он просто загружает данные в redis), а затем обрабатывается фоновым процессом (см. документацию о том, как настроить и запустить работников).
Пожалуйста, обратите внимание, что это будет полезно в вашем случае только в двух случаях:
- Ваше приложение всегда находится под большой нагрузкой или нужно особенно хорошо время отклика
- Вы делаете большие вычисления в
Impression#before_create
или других обратных вызовов
Если вы не согласны с одним из этих условий, вероятно, более эффективно просто создать впечатление на создание фильтра в контроллере: доступ к базе данных имеет стоимость, но не настолько, чтобы пользователь чувствовал, когда вы ke - единственная вставка в базу данных.
Отличный ответ, спасибо! –