Rails Devise gem - customizing default User model

2019-05-08 05:21发布

问题:

I have tried the devise rails gem, and was wondering what the best way would be to split the user model attributes it creates across multiple models.

For now, my user model looks as follows, which is the default devise behaviour:

User(id: integer, email: string, encrypted_password: string, password_salt: string, reset_password_token: string, remember_token: string, remember_created_at: datetime, sign_in_count: integer, current_sign_in_at: datetime, last_sign_in_at: datetime, current_sign_in_ip: string, last_sign_in_ip: string, created_at: datetime, updated_at: datetime)

I would like to have some of the attributes below in another model, e.g. Watchdog

sign_in_count, current_sign_in_at, last_sign_in_at, current_sign_in_ip, last_sign_in_ip

I was considering of simple delegating them using the delegate method:

delegate :sign_in_count, :sign_in_count=, ..., :to => :watchdog

Would be interested in hearing about better solutions to this problem.

Thanks,

Sergio

回答1:

You can also create your own concern that does the same without having to override Devise internals. After doing that, only extend Trackable module on your model.

    module Trackable
      def update_tracked_fields!(request)
        old_current, new_current = watchdog.current_sign_in_at, Time.now.utc
        watchdog.last_sign_in_at     = old_current || new_current
        watchdog.current_sign_in_at  = new_current

        old_current, new_current = self.current_sign_in_ip, request.ip
        watchdog.last_sign_in_ip     = old_current || new_current
        watchdog.current_sign_in_ip  = new_current

        watchdog.sign_in_count ||= 0
        watchdog.sign_in_count += 1

        watchdog.save(:validate => false)
      end
    end

But don't forget to put record.update_tracked_fields!(warden.request) on the Warden::Manager.after_set_user block as we do on Devise hook.