【问题标题】:Rails Devise model won't use custom model controller?Rails Devise 模型不会使用自定义模型控制器?
【发布时间】:2014-02-19 18:11:20
【问题描述】:

在 Rails(4.0.2 版)中,我使用 Devise gem(3.0.4 版)生成了一个简单的模型,名为 User。我想自定义控制器。所以我做了一个文件“user_controller”:

class UserController < Devise::SessionsController

def create
    super
    puts "this works"

end

end

这是我的路线:

SecretApp::Application.routes.draw do

root  'static_pages#home'
match '/about',   to: 'static_pages#about',   via: 'get'
match '/profile', :to => "profile#show",       via:'get'

devise_for :users, :controllers => {:registrations => "registrations", :sessions => "user"}

end

我假设在覆盖 Devise 控制器时,您必须在每个方法中调用 super,除非您完全覆盖该方法,对吗?无论如何,当我创建一个新用户时,控制台永远不会打印“this works”,所以我很确定控制器没有被使用。为什么?

然而,我确实设法为 User 模型覆盖了我的注册控制器,这让我感到困惑,因为我使用相同的方法来覆盖 User 控制器(除了继承的超类和控制器名称)。我确信这一点,因为我在 new 方法中有 puts "this is ok",它确实将其打印到控制台。

【问题讨论】:

  • Devise::SessionsController 处理会话(登录/注销等),但您正在谈论创建用户,这将由 Devise::Registrations 处理。您还说您已成功覆盖注册控制器。你能澄清你在问什么吗?
  • 我在问如何为 Devise 模型制作自定义控制器类。长话短说,注册后,我有一个用户的嵌套表单和一个Profile 模型(每个用户都有一个Profile)。 Devise 没有将配置文件属性保存到配置文件模型中。所以我需要在创建用户时分配它们,因此需要用户自定义控制器。根据this Devise::SessionsController 是自定义控制器的正确超类。
  • 我认为您可能误解了他们的示例,该示例涉及会话管理。如果要处理用户创建,请使用class UsersController &lt; Devise::RegistrationsController

标签: ruby-on-rails ruby devise controller overriding


【解决方案1】:

我同意扎克的观点。从Devise::SessionsController 继承的控制器绝对不应该称为UserController。最多,该控制器应该从Devise::RegistrationsController 继承。此外,Rails 的约定要求您以复数形式命名控制器,UsersController。无论如何,这就是您的代码无法正常工作的原因:

当您调用super 时,会到达Devise::SessionsController 中的create 操作。请注意,在该操作的最后一行,respond_with 方法是如何被调用的。此方法负责渲染模板,生成响应。一旦到达此行,您的代码将不会运行。

您有两个选择:

  1. 在调用super之前调用您的自定义代码:

    def create
      puts "this works"
      super
    end
    
  2. 或者利用 Devise 的 create 操作具有这一行的事实:

    yield resource if block_given?
    

    然后您可以像这样调用您的自定义代码:

    def create
      super do |resource|
        puts "this works"
      end
    end
    

    这在Devise's readme中都有提到。

在第二个选项中,Devise 使用了两个很棒的 Ruby 特性:块和屈服。您可以通过RubyMonk 了解更多关于块和产量的信息,我强烈推荐它!

【讨论】:

  • 这可能违反直觉,但在这种情况下,Rails 执行您在super 之后包含的任何内容,只要达到该方法(它可以让您做一些事情)在渲染或重定向之后)。 Here 就是一个例子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-29
  • 1970-01-01
相关资源
最近更新 更多