Soru Raylar: Kullanıcının “en son gördüğü” zamanı nasıl gösterir?


Ben hangi mağazalarda kullanıyorum current_sign_in_at ve last_sign_in_at tarihsaat.

Ancak, bir kullanıcı bir ay önce giriş yaptığını ancak en son 5 dakika önce bir sayfayı görüntülediğini söyleyebilir mi?

Bunu gösterebilmemin bir yolu var mı?"Kullanıcı son 5 dakika önce görüldü").


22
2017-12-29 01:52


Menşei




Cevaplar:


Buna ne dersin:

  1. Kullanıcının son görüldüğü tarih ve saati saklamak için kullanıcılara yeni bir alan eklemek için bir geçiş oluşturun:

    rails g migration add_last_seen_at_to_users last_seen_at:datetime
    
  2. Uygulama denetleyicinize önce bir harekete geri arama ekleyin:

    before_action :set_last_seen_at, if: proc { user_signed_in? }
    
    private
    def set_last_seen_at
      current_user.update_attribute(:last_seen_at, Time.current)
    end
    

Bu şekilde, mevcut kullanıcının gerçekleştirdiği her istek (yani etkinlik), en son görülen özniteliği güncel zamana güncellenir.

Ancak, oturum açmış bir çok kullanıcınız varsa bu durumun uygulamanızın bazı kaynaklarını alabileceğini lütfen unutmayın. Çünkü bu, giriş yapmış biri tarafından talep edilen tüm denetleyici işlemlerinden önce yürütülür.

Performans bir sorun teşkil ediyorsa, 2. adımda aşağıdaki gaz kelebeği mekanizmasını eklemeyi düşünün (bu örnekte, 15 dakika kısılması):

before_action :set_last_seen_at, if: proc { user_signed_in? && (session[:last_seen_at] == nil || session[:last_seen_at] < 15.minutes.ago) }

private
def set_last_seen_at
  current_user.update_attribute(:last_seen_at, Time.current)
  session[:last_seen_at] = Time.current
end

42
2017-12-29 01:58



Sağol Charles. Bu benim endişem - mümkün olan en düşük kaynak kullanımıyla bunu başarmanın bir yolu var mı? Her sayfa görünümünde db için bir güncelleme çok fazla olacak :) - Hopstream
Burada daraltmak için bir oturum değişkenini kullanmanın bir anlamı yok. Sadece kullan current_user.last_seen_at doğrudan değer. - Ryan McGeary
@Lorenz No. current_user zaten veritabanından ve onunla getirildi, last_seen_at aynı zamanda değer. - Ryan McGeary
@Lorenz Düşünceleriniz doğru; Ancak, bunlar karşılaştırdığımız iki zaman damgası. x < 15.minutes.ago? İngilizce gibi okur bu yüzden kafa karıştırıcı, ama gerçekten ne anlama geliyor "Bu zaman damgası x 15 dakika önce zaman damgası daha az mı". “15 dakikadan daha uzun bir süre önce” diye sormakla aynı şey, çünkü geçmişte daha fazla zaman damgası daha küçük olacaktır. Umarım bu şeyleri temizler :) - weltschmerz
kullanmak daha iyi update_column yerine update_attribute - aksi halde güncelleniyor updated_at Kullanıcı modelinde tanımlanan tüm geri çağrıları tetiklemenin yanı sıra, büyük olasılıkla istenen davranış değildir - trushkevich


Önceki cevabın performansını artırmak için:

  • Kullanıcı zaten müdürle yüklendiği ve tüm özniteliklere erişilebilir olduğu için oturumu kullanmayın
  • update_attribute geri aramaları ve güncellemeleri çalıştırır updated_at özellik ve update_column değil
  • Performansı iyileştirmek, ActiveJob / Resque / Sidekiq gibi arka plan işçilerini kullanmak daha iyi
  • DB kilitlemeyi engellemek, kullanıcı tablosuyla ilişkilendirilmiş ayrı bir tablo oluşturmak ve oraya yazma girişlerini önlemek için

Güncelleme kodu:

before_action :set_last_seen_at, if: proc { user_signed_in? && (user.last_seen_at.nil? || user.last_seen_at < 15.minutes.ago) }

private
def set_last_seen_at
  current_user.update_column(:last_seen_at, Time.now)
end

Devise eklentisi benzer davranışın gerçekleşmesini sağlar (en son görülme, optimizasyon olmadan): https://github.com/ctide/devise_lastseenable


3
2018-03-23 17:58