[RUBY] Le problème que l'attribut du modèle User devient nul dans ActionMailer

Environnement d'exécution

Ce que j'essayais de faire

Envoyer un e-mail lors de la création d'un nouvel utilisateur

app/controllers/users_controller.rb


class UsersController < ApplicationController
  def create
    @user = User.new(user_params)
    if @user.save
      UserMailer.activation(@user).deliver_later
      redirect_to root_url
    else
      render "new"
    end
  end
end

Passer l'objet utilisateur

app/mailers/user_mailer.rb


class UserMailer < ApplicationMailer
  def activation(user)
    @user = user
    mail(to: @user.email, subject: 'Veuillez activer votre compte')
  end
end

Envoyer un jeton d'activation

app/views/user_mailer/activation.html.slim


p= "Bonjour,#{@user.name}M."

Cliquez sur le lien p pour activer votre compte
= link_to "Activer le compte", edit_account_activation_url(@user.activation_token, email: @user.email)

Le jeton d'activation est créé à l'utilisateur create

app/models/user.rb


class User < ApplicationRecord
  attr_accessor :activation_token
  before_create :create_activation_digest

  private
    def create_activation_digest
      self.activation_token = SecureRandom.urlsafe_base64
      self.activation_digest = BCrypt::Password.create(activation_token)
    end
end

Erreur survenue

ActionView::Template::Error (No route matches {:action=>"edit", :controller=>"account_activations", :email=>"adresse", :id=>nil}, possible unmatched constraints: [:id]):

«@ user.activation_token» est devenu «nul»

Examinez l'erreur

Si vous regardez @ user.object_id et @ user.activation_token

44860
"I2BCoTsomoNhqNF0q_zRKw"
[ActiveJob] -----

  User Load (0.8ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 70], ["LIMIT", 1]]

[ActiveJob] -----
44980
nil

C'est un objet différent et ʻactivation_token est également nil`!

Cause d'erreur

deliver_later

Si vous envoyez un e-mail avec livrer_later, vous pouvez voir qu'il recherche un utilisateur dans la base de données avant d'exécuter ʻUserMailer`.

  User Load (0.8ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2  [["id", 70], ["LIMIT", 1]]

La valeur de l'attribut ʻactivation_token ne peut pas être référencée dans l'objet ʻuser obtenu à partir de la base de données après l'enregistrement car il n'a que le @ user lorsque @ user.save est exécuté.

Solution

Utilisez delivery_now

app/controllers/users_controller.rb


class UsersController < ApplicationController
  def create
    @user = User.new(user_params)
    if @user.save
      UserMailer.activation(@user).deliver_now
      redirect_to root_url
    else
      render "new"
    end
  end
end

Si vous envoyez avec delivery_now, l'argument sera passé tel quel, donc il réussira!

37900
"2kQLrYZjinTiJFKE3jdPqQ"
37900
"2kQLrYZjinTiJFKE3jdPqQ"

Résumé de delivery_now et delater_later

deliver_now Envoyez un email immédiatement

deliver_late ʻEnvoyer le courrier plus tard en utilisant Active Job`

https://railsguides.jp/active_job_basics.html#action-mailer

https://api.rubyonrails.org/classes/ActionMailer/MessageDelivery.html#method-i-deliver_later

Recommended Posts

Le problème que l'attribut du modèle User devient nul dans ActionMailer
Le problème que le contenu des paramètres est complètement affiché dans la vue [Rails]
Le problème que le répertoire de montage de Docker Desktop avec WSL2 comme back-end devient étrange dans Windows Terminal (non résolu à partir du 29/08/2020?)
À propos du problème de blocage dans le traitement parallèle dans la version 4.0 de gem'sprockets
[Rails] Enregistrez-vous par attribut du même modèle en utilisant Devise
Quelle est la représentation de la connaissance du domaine dans le modèle [DDD]?
Résolution du problème d'affichage de toutes les données du tableau
Suivre le mémorandum d'association de fonction (comprendre la description du modèle utilisateur)
Un programme qui compte le nombre de mots dans une liste
Correction du problème selon lequel le nom de la fabrique de connexions de TcpConnectionOpenEvent émis par TcpConnection qui définissait l'intercepteur devenait inconnu.
Le problème de la réorganisation arbitraire des attributs XML dans Android Studio
Formulaire qui reçoit la valeur de l'élément répétitif dans Spring MVC
Je veux changer la valeur de l'attribut dans Selenium of Ruby
Ceci et cela de JDK
Un mémorandum du problème FizzBuzz
Ordre de traitement dans le programme
Cas où les utilisateurs sont déconnectés lors de la modification d'une application (rails)
Ceci et cela de la mise en œuvre du jugement en temps réel des dates en Java
Exemple de programme qui renvoie la valeur de hachage d'un fichier en Java
Ignorer les paramètres qui n'existent pas dans le modèle avec ObjectMapper # readValue
[Java] java.lang.NoClassDefFoundError: Résolution du problème de chute dans org / jsoup / safety / Whitelist
J'obtiens des erreurs: l'utilisateur doit exister dans le test du modèle unitaire