问题 使用Devise的上下文“super”和“super do | u |”之间的区别


好的,我觉得我得到的超级棒 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

7412
2018-05-24 18:30


起源

他们的 new 采取一个块(因此 yield) - Anthony


答案:


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

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

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

respond_with self.resource

14
2018-05-24 18:46



我明白了,所以在这种情况下,因为有一个 super 和a yield 到了块,然后基本上是代码中的 super do 无论何处都被执行 yield 叫做。在这种情况下,它允许我在父操作的中间注入代码。如果没有 yield 声明,然后 super do 会没用,而且 super 单独运行整个父操作(意味着我可以在开头或结尾注入代码)。那是对的吗? - james