Rails - 如何覆盖设计SessionsController以在用户登录时执行特定任务?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Rails - 如何覆盖设计SessionsController以在用户登录时执行特定任务?相关的知识,希望对你有一定的参考价值。

使用Devise管理用户会话/注册我需要每次用户登录时,以及在通过设计重定向到主页以进行连接之前执行特定任务(例如,更新此特定用户的users表中的某些字段)用户。

我是否必须覆盖设计SessionsController,如果是,如何?

答案

或者,您可以创建自己的会话控制器

class SessionsController < Devise::SessionsController
  def new
    super
  end

  def create
    self.resource = warden.authenticate!(auth_options)
    set_flash_message(:notice, :signed_in) if is_navigational_format?
    sign_in(resource_name, resource)
    if !session[:return_to].blank?
      redirect_to session[:return_to]
      session[:return_to] = nil
    else
      respond_with resource, :location => after_sign_in_path_for(resource)
    end
  end
end

并在routes.rb添加:

devise_for :users, controllers: {sessions: "sessions"}
另一答案

Devise提供after_database_authentication回调方法。您可以完全访问当前经过身份验证的用户对象。

如果要在每次成功登录后更新当前用户名,可以执行以下操作。

class User < ActiveRecord::Base
  devise :database_authenticatable

  def after_database_authentication
    self.update_attributes(:name => "your name goes here")
  end 
end
另一答案

如果你看一下Devise's implementationsessions_controller#create,你会注意到如果你通过了一个区块他们会屈服。

因此,只需将其会话控制器子类化,并在调用super时传递一个块。要做到这一点,首先告诉routes.rb中的Devise你想使用自己的会话控制器:

devise_for :users, controllers: { sessions: 'users/sessions' }

然后创建一个SessionsController类,并在create方法中调用super时传递一个块。它看起来像这样:

class Users::SessionsController < Devise::SessionsController
  layout "application"

  # POST /login
  def create
    super do |user|
      if user.persisted?
        user.update(foo: :bar)
      end
    end
  end
end

大多数Devise控制器方法接受一个块,所以你可以这样做注册,忘记密码等。

以上是关于Rails - 如何覆盖设计SessionsController以在用户登录时执行特定任务?的主要内容,如果未能解决你的问题,请参考以下文章

rails:如何覆盖 cocoon gem 辅助方法并调用原始方法

如何从 Rails 中的 gem 覆盖类的方法?

rails: 如何基于子域覆盖locale?

Ruby/Rails:您如何自定义 Devise 的邮件模板?

Ruby/Rails:您如何自定义 Devise 的邮件模板?

Rails:设计 + CanCan 看不到任何视图