我有一个与devise gem集成的用户表。该表包含某些字段,如current_sign_in_ip,last_sign_in_ip,current_sign_in_at等。当用户登录时,Devise会修改这些字段。 我希望将这些字段移动到另一个表并通过设计或其他方式填充它们。有没有办法实现这个目标?
答案 0 :(得分:4)
这个答案有两种方法:
第一个(更容易,但不是很漂亮)选项是将:trackable
方法委托给第二个类(下面称为UserDetail)。例如:
class UserDetail < ActiveRecord::Base
...
end
class User < ActiveRecord::Base
delegate :current_sign_in_ip, :last_sign_in_ip .... to: :user_detail
...
end
更清洁的选项会创建一个避免覆盖Devise的问题。您必须将其扩展到User
模型:
module Trackable
def update_tracked_fields!(request)
old_current, new_current = user_detail.current_sign_in_at, Time.now.utc
user_detail.last_sign_in_at = old_current || new_current
user_detail.current_sign_in_at = new_current
old_current, new_current = self.current_sign_in_ip, request.ip
user_detail.last_sign_in_ip = old_current || new_current
user_detail.current_sign_in_ip = new_current
user_detail.sign_in_count ||= 0
user_detail.sign_in_count += 1
user_detail.save(:validate => false)
end
end
我通过this link.从罗德里戈·弗洛雷斯那里得到了第二个解决方案他提醒我们将record.update_tracked_fields!(warden.request)
放在Warden::Manager.after_set_user
区块上,就像他们一样here.
答案 1 :(得分:0)
感谢您的回复。它帮助我朝着正确的方向前进。 让我分享一下我如何解决我面临的问题。
由于我想要用户和user_logs表之间的一对多关系,我无法将可跟踪方法委托给UserLog模型。 另外,我希望user_logs表是一个只插入表,因此我需要相应地覆盖Devise Trackable模块的update_tracked_fields方法。
所以:
我创建了一个新的user_logs表和UserLog模型。
覆盖update_tracked_fields方法,以便每次在user_logs表中实际插入新行,而不是更新用户表。
在User模型中为这些可跟踪字段创建了getter方法,实际从user_logs表中获取所需的列值。像这样:
self.try(:user_logs).last.try(:current_sign_in_ip)