2015-05-24 7 views
9

Ok, quindi penso di ottenere ciò che super does standalone. Fondamentalmente in Devise, se , quindi su qualsiasi azione, avendo un super chiamerà prima la logica per la stessa azione denominata nel genitore Devise::RegistrationsController, prima di chiamare ciò che hai scritto.Differenza tra "super" e "super do | u |" utilizzando il contesto di Devise

In altre parole ...

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" 

Quello che mi incuriosisce è che ho visto alcune persone lo fanno:

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

Sto avendo un momento difficile confezionamento mia gira intorno a ciò che sta facendo il do block. Nel mio caso, dopo aver creato la risorsa (l'utente), voglio chiamare un metodo aggiuntivo su quella risorsa (l'utente).

codice attuale:

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

Mi chiedo solo se questo sarebbe diverso che farlo:

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

Nel caso in cui è utile, ho incluso il codice genitore Devise::RegistrationsController qui di seguito:

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

bene il loro 'metodo new' prende un blocco (da qui il' yield') – Anthony

risposta

12

Lasciami provare a spiegare cosa sta succedendo qui:

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

Quando si sta chiamando super, si sta andando indietro al genitore new azione, quindi il seguente codice sarà eseguendo ora:

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

Ma aspetta ... Ecco un yield, quindi produce la corrente resource al blocco, si può pensare al blocco come un metodo, ha bisogno di un parametro (user), e qui resource (dai genitori) sarà il parametro:

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

Ora, poiché il blocco viene eseguito completamente, inizierà l'esecuzione di nuovo il super:

respond_with self.resource 
+0

Vedo, quindi in questo caso dato che c'è un 'super' e un' yield' al blocco, quindi in pratica il codice nel 'super do' viene eseguito ovunque venga chiamato' yield'. In questo caso, mi consente di iniettare il codice nel mezzo dell'azione principale. Se NON ci fosse un'istruzione 'yield', allora' super do' sarebbe inutile, e 'super' da solo eseguirà l'intera azione genitore (cioè potrei iniettare il codice sia all'inizio che alla fine). È corretto? – james