2016-07-09 5 views
1

Il est vraiment difficile de comprendre comment un formulaire fonctionne avec hidden_field_tag ​​dans une situation spécifique. J'aimerais que quelqu'un m'explique ce qui se passe.Comment fonctionne hidden_field_tag ​​dans un formulaire de réinitialisation du mot de passe

Il s'agit du formulaire de réinitialisation du mot de passe railstutorial.

Mon point de vue est le suivant:

<% provide(:title, 'Reset password') %> 
<h1>Reset password</h1> 

<div class="row"> 
    <div class="col-md-6 col-md-offset-3"> 
    <%= form_for(@user, url: password_reset_path(params[:id])) do |f| %> 
     <%= render 'shared/error_messages', object: f.object %> 

     <%= hidden_field_tag :email, @user.email %> 

     <%= f.label :password %> 
     <%= f.password_field :password, class: 'form-control' %> 

     <%= f.label :password_confirmation, "Confirmation" %> 
     <%= f.password_field :password_confirmation, class: 'form-control' %> 

     <%= f.submit "Update password", class: "btn btn-primary" %> 
    <% end %> 
    </div> 
</div> 

Mon action de mise à jour et la méthode forte params:

def update 
    if params[:user][:password].empty? 
     @user.errors.add(:password, "can't be empty") 
     render 'edit' 
    elsif @user.update_attributes(user_params) 
     log_in @user 
     @user.update_attribute(:reset_digest, nil) 
     flash[:success] = "Password has been reset." 
     redirect_to @user 
    else 
     render 'edit' 
    end 
    end 

    private 

    def user_params 
    params.require(:user).permit(:password, :password_confirmation) 
    end 

Lorsque l'accès de l'action d'édition, l'utilisateur d'entrer un message électronique envoyé à l'application envoyer un lien vers cette email, avec un token d'activation, comme ce chemin:

/password_resets/9Ij91DFChTeWTitNDVJfYw/edit?email=example%40railstutorial.org 

L'utilisateur ouvre ce lien et change le mot de passe. C'est parfaitement fonctionnel. Ma question est: si j'ai déjà l'utilisateur de l'action d'édition et n'utilise pas explicitement params[:email] (fourni avec le hidden_field_tag) dans mon action de mise à jour, pourquoi ai-je besoin de la balise cachée?

Répondre

1

Les actions sont séparées les unes des autres. Lorsque vous affichez votre formulaire de réinitialisation de mot de passe pour la première fois dans l'action edit, votre variable d'instance @user, qui a déjà été initialisée, est utilisée pour fournir une valeur pour le champ de courrier électronique masqué.

Lorsque l'utilisateur ultérieur soumet le formulaire, ses données sont traitées par l'action update dans une requête complètement séparée. Cette demande ne sait pas ce qui s'est passé avant, spécifiquement, que le formulaire a été rendu à l'origine par l'action edit. Il n'a également accès à aucun des objets qui étaient dans la portée de l'action edit. Pour traiter la demande, votre code d'action update doit initialiser tous les objets dont il a besoin à nouveau, et c'est principalement l'objet @user.

Si l'action en cours ne sait pas ce qui s'est passé avant, comment elle connaitrait quel enregistrement utilisateur devrait aller à la variable @user? Il peut trouver l'utilisateur par email, c'est pourquoi vous l'avez fourni dans les paramètres. Votre code d'action edit l'a rendu disponible pour la prochaine demande. Du point de vue de votre action edit, il devrait déjà y avoir une méthode dans votre contrôleur qui initialise l'objet @user avant que le code d'action ne soit exécuté. Recherchez le rappel before_action. La méthode recherche probablement l'utilisateur par l'email passé dans le params. Lorsque l'action elle-même est exécutée, l'objet @user est déjà présent, Rails peut donc sembler savoir comment l'obtenir. Ce n'est pas le cas, le code de votre contrôleur le permet.

Par conséquent, vous avez besoin d'une balise masquée pour transmettre le contexte entre les actions. Il y a d'autres façons de le faire, comme utiliser session ou cookies, mais c'est probablement le plus simple.

+0

vous frappez l'oeil de taureau! J'ai une action '' before_action'' pour l'action '' update'', trouvant l'utilisateur par '' params [: email] ''. Cela fait beaucoup plus de sens maintenant, merci! – rwehresmann

+0

@nic ce que vous voulez dire en disant que nous pouvons utiliser 'session' ou' cookies'?l'utilisateur ne se connecte pas encore, il a oublié le mot de passe – truongnm

+0

Session et les cookies sont disponibles indépendamment du fait que l'utilisateur est connecté ou non. C'est le choix du programmeur que placer dans l'un ou l'autre. –