"super" 和 "super do |u|" 使用 Devise 上下文的区别

Difference between "super" and "super do |u|" using context of Devise

好的,我想我得到了超级 does 独立的东西。基本上在 Devise 中,如果 Users::RegistrationsController < Devise::RegistrationsController,那么在任何操作上,super 将首先调用父 Devise::RegistrationsController 中相同命名操作的逻辑,然后再调用您编写的内容.

换句话说...

class Devise::RegistrationsController
  def new
    puts "this is in the parent controller"
  end
end

class Users::RegistrationsController < Devise::RegistrationsController
  def new
    super
    puts "this is in the child controller"
  end
end

# Output if users#new is run would be:
# => "this is in the parent controller"
# => "this is in the child controller"

# If super were reversed, and the code looked like this
# class Users::RegistrationsController < Devise::RegistrationsController
  #  def new
    #  puts "this is in the child controller"
    #  super
  #  end
#  end
# Then output if users#new is run would be:
# => "this is in the child controller"
# => "this is in the parent controller"

我很好奇的是,我看到有人这样做:

class Users::RegistrationsController < Devise::RegistrationsController
  def new
    super do |user|
      puts "something"
    end
  end
end

我很难理解 do block 正在完成的工作。在我的例子中,在创建资源(用户)之后,我想对该资源(用户)调用一个额外的方法。

当前代码:

class Users::RegistrationsController < Devise::RegistrationsController
  def new
    super do |user|
      user.charge_and_save_customer
      puts user.inspect
    end
  end
end

我只是想知道这是否与以下操作有什么不同:

class Users::RegistrationsController < Devise::RegistrationsController
  def new
    super
    resource.charge_and_save_customer
    puts resource.inspect
  end
end

如果有用,我在下面包含了父 Devise::RegistrationsController 代码:

def new
  build_resource({})
  set_minimum_password_length
  yield resource if block_given?
  respond_with self.resource
end

让我试着解释一下这里发生了什么:

class Users::RegistrationsController < Devise::RegistrationsController
  def new
    super do |user|
      user.charge_and_save_customer
      puts user.inspect
    end
  end
end

当您调用 super 时,您将返回到父 new 操作,因此现在将执行以下代码:

def new
  build_resource({})
  set_minimum_password_length
  yield resource if block_given?
  respond_with self.resource
end

但是等等...这里有一个 yield,所以它产生当前的 resource 给块,你可以把块想象成一个方法,它需要一个参数(user),这里 resource(来自父级)将是参数:

# Here resource is assigned to user
user.charge_and_save_customer
puts user.inspect

现在,由于块已完全执行,它将再次开始执行超级:

respond_with self.resource