好的,所以我觉得我得到了超级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
答案 0 :(得分:15)
让我试着解释一下这里发生了什么:
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
答案 1 :(得分:0)
堆栈溢出霸主不会让我发表评论,因为我没有任何互联网积分,但这是对“如果没有 yield 语句,super 会没有用吗?”这个问题的答案。在 michaelrbock 答案的评论部分。
如果super调用的方法中没有yield语句(或者等价的),那么super do块中的代码就不会被执行。但是,ruby 不会警告您该块未在运行,因此可能会产生误导。