Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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
like image 664
james Avatar asked May 24 '15 18:05

james


People also ask

What is resource in devise?

Resource is an abstraction name of instance of a user. It can be configured in devise settings to work with Admin model or any other. By default it's the first devise role declared in your routes devise :users # resource is instance of User class devise :admins # resource is instance of Admin class.

What is the difference between Super() and this() in JavaScript?

Last Updated : 23 Nov, 2017 Similar article : super and this keyword super () as well as this () both are used to make constructor calls. super () is used to call Base class’s constructor (i.e, Parent’s class) while this () is used to call current class’s constructor. Let’s see both of them in detail:

What is the use of Super in Java?

The super keyword in java is a reference variable that is used to refer parent class objects. The keyword “super” came into the picture with the concept of Inheritance. Basically this form of super is used to initialize superclass variables when there is no constructor present in superclass.

What is the difference between “Super” and “superb?

Both “super” and “su­perb” are com­mon, but they are not com­pletely in­ter­change­able. Super is used nowa­days mostly as an ad­verb mean­ing “very, re­ally”, for ex­am­ple: The food was super delicious. = The food was really delicious. She was super friendly. = She was very friendly.

What is the difference between this() and Super() statements in C++?

Note: super () should be first statement inside any constructor. It can be used only inside constructor and nowhere else. super () is used to refer only parent class’s (super class’s) constructor. this () is used to call the current class’s constructor . RR class's 1 arg const Flow comes back from RR class's 1 arg const Inside Main


Video Answer


1 Answers

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
like image 97
Sharvy Ahmed Avatar answered Oct 24 '22 20:10

Sharvy Ahmed