Ok so I think I get what super does
standalone. Basically in Devise, if Users::RegistrationsController < Devise::RegistrationsController
, then on any action, having a super
will first call the logic for that same named action in the parent Devise::RegistrationsController
, before then calling what you've written.
In other words...
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"
What I'm curious about is that I've seen some people do this:
class Users::RegistrationsController < Devise::RegistrationsController
def new
super do |user|
puts "something"
end
end
end
I'm having a hard time wrapping my head around what the do block
is accomplishing. In my case, after the resource (the user) is created, I want to call an additional method on that resource (the user).
Current code:
class Users::RegistrationsController < Devise::RegistrationsController
def new
super do |user|
user.charge_and_save_customer
puts user.inspect
end
end
end
I'm just wondering if this would be any different than doing:
class Users::RegistrationsController < Devise::RegistrationsController
def new
super
resource.charge_and_save_customer
puts resource.inspect
end
end
In case it's helpful, I've included the parent Devise::RegistrationsController
code below:
def new
build_resource({})
set_minimum_password_length
yield resource if block_given?
respond_with self.resource
end
Let me try to explain what is going on here:
class Users::RegistrationsController < Devise::RegistrationsController
def new
super do |user|
user.charge_and_save_customer
puts user.inspect
end
end
end
When you call super
, you are going back to the parent new
action, so the following code will be executing now:
def new
build_resource({})
set_minimum_password_length
yield resource if block_given?
respond_with self.resource
end
But wait... here is an yield
, so it yields the current resource
to the block, you can think of the block like a method, it needs a parameter (user
), and here resource
(from parent) will be the parameter:
# Here resource is assigned to user
user.charge_and_save_customer
puts user.inspect
Now, since the block is executed completely, it will start executing the super again:
respond_with self.resource