2013-09-09 2 views
1

Я хочу сохранить информацию о запросах к определенному действию в модели с именем Impression.Сохранение запросов для определенного действия

Я предполагаю, что это benificial для времени отклика посетителя, чтобы сохранить эту информацию в after_filter, например:

after_filter :save_impression 


private 
    def save_impression 
     Impression.create!(ip_address: request.remote_ip, controller_name: params[:controller], action_name: params[:action], referer: request.referer) 
    end 

Может ли этот код оптимизировать или я делаю это правильно?

ответ

2

Хорошее решение для этого, как правило, связаны с использованием работника. Все, что не является критически важным для запроса и которое связано с сложными вычислениями, может быть отложено и запущено позже фоновым заданием.

Две общие реализации рабочих: 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), а затем обрабатывается фоновым процессом (см. документацию о том, как настроить и запустить работников).

Пожалуйста, обратите внимание, что это будет полезно в вашем случае только в двух случаях:

  1. Ваше приложение всегда находится под большой нагрузкой или нужно особенно хорошо время отклика
  2. Вы делаете большие вычисления в Impression#before_create или других обратных вызовов

Если вы не согласны с одним из этих условий, вероятно, более эффективно просто создать впечатление на создание фильтра в контроллере: доступ к базе данных имеет стоимость, но не настолько, чтобы пользователь чувствовал, когда вы ke - единственная вставка в базу данных.

+0

Отличный ответ, спасибо! –

1

Это все равно будет выполняться перед рендерингом. Чтобы запустить после рендеринга/перенаправления, вам нужно создать отдельный поток.

See this question