1

我试图通过设计来记录用户连续登录(天)的数量。

向用户表添加了一个新列 time_since_sign_in 整数。

覆盖设计会话控制器

devise_for :users, controllers: { sessions: "sessions" }

添加了这个我认为会在登录之前更新 attr

class SessionsController < Devise::SessionsController
  def create
    current_user.update_sign_in_streak
    # even if i comment out super, last_sign_in_at still gets updated
    super
  end
end

添加到用户模型

def update_sign_in_streak
  # binding.pry
  # at this point last_sign_in_at always updated
  time_since_sign_in = Time.now - last_sign_in_at
  if time_since_sign_in.between?(1.day, 2.day)
    increment! :sign_in_streak
  elsif time_since_sign_in > 2.day
    sign_in_streak = 0
    save
  end
end

所以显然设计有这个钩子,它更新跟踪字段。但是为什么在创建成功之前会调用它?关于如何让这个工作的任何想法?

Warden::Manager.after_set_user :except => :fetch do |record, warden, options|
  if record.respond_to?(:update_tracked_fields!) && warden.authenticated?(options[:scope]) && !warden.request.env['devise.skip_trackable']
    record.update_tracked_fields!(warden.request)
  end
end
4

1 回答 1

0

我想出了一个不好的技巧,但是如果有人有更好的答案,请告诉我

(顺便说一句,问题再次是 last_sign_in_at attr 在创建操作之前在 prepend_before_filter 中更新,所以我永远无法访问 last_sign_in_at 值)

分叉设计!

可追踪模型

def update_tracked_fields!(request)
  update_sign_in_streak

  # ...
end

def update_sign_in_streak
  time_since_sign_in = Time.now - self.last_sign_in_at
  if time_since_sign_in.between?(1.day, 2.day)
    self.sign_in_streak += 1
  elsif time_since_sign_in > 2.day
    self.sign_in_streak = 1
  end
end
于 2013-07-06T23:12:17.773 回答