将设计用户表拆分为两个表

时间:2015-12-29 12:30:16

标签: ruby-on-rails ruby devise

我有一个与devise gem集成的用户表。该表包含某些字段,如current_sign_in_ip,last_sign_in_ip,current_sign_in_at等。当用户登录时,Devise会修改这些字段。 我希望将这些字段移动到另一个表并通过设计或其他方式填充它们。有没有办法实现这个目标?

2 个答案:

答案 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方法。

所以:

  1. 我创建了一个新的user_logs表和UserLog模型。

  2. 覆盖update_tracked_fields方法,以便每次在user_logs表中实际插入新行,而不是更新用户表。

  3. 在User模型中为这些可跟踪字段创建了getter方法,实际从user_logs表中获取所需的列值。像这样:

    self.try(:user_logs).last.try(:current_sign_in_ip)