質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.63%

user.authenticated?(:activation, params[:id])がfalseになり、アカウント有効化が出来ない

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 148

メールは送ることができて、メールからアカウント有効化のボタンを押しても「無効なアカウントリンクです。」とでてしまいます。
editアクション内のif文のuser、!user.activated?はtrueになっていたので、user.authenticated?(:activation, params[:id])がfalseになっているんだと思います。
有効化するにはどうしたらいいでしょうか?
cloud9、heroku、sendgrid、s3を使っています。
(account_activations_controller.rb)

class AccountActivationsController < ApplicationController

  def edit
    user = User.find_by(email: params[:email])
    if user && !user.activated? && user.authenticated?(:activation, params[:id])
      user.activate
      log_in user
      flash[:success] = "アカウントが有効化されました。"
      redirect_to user
    else
      flash[:danger] = "無効なアカウントリンクです。"
      redirect_to root_url
    end
  end

end


(account_activation.html.erb)

<p><%= @user.name %>さん</p>
<p>
アカウントを有効にするには、以下のリンクをクリックしてください。
</p>
<%= link_to "アカウントを有効化する", edit_account_activation_url(@user.activation_token,email: @user.email) %>


(users_controller.rb)

class UsersController < ApplicationController
  before_action :logged_in_user, only: [:index, :edit, :update, :destroy]
  before_action :correct_user,   only: [:edit, :update]
  before_action :admin_user,     only: :destroy

  def index
    if current_user.admin==true
    users=User.paginate(page: params[:page], per_page: 10)
    @users=users.order(created_at: "desc")
    else
      redirect_to root_path
      flash[:danger]="そのページは存在しません"
    end
  end
  def user_posts
   @user = User.find(params[:id])
   posts=@user.posts.paginate(page: params[:page], per_page: 10)
   @posts= posts.order(created_at: "desc")
  end
  def new
    @user = User.new
  end
  def followposts
    @user=User.find(params[:user_id])
    posts=Post.paginate(page: params[:page], per_page: 10)
    @posts=posts.order(created_at: "desc")

    @followusers=@user.followings
    @followposts = @posts.where(user_id: @followusers)

  end
  def show
    @user = User.find(params[:id])
    @postsall= @user.posts.all.order(created_at: "desc")
    @likes= @user.likes
    @posts=Post.all.order(created_at: "desc")
    @followusers=@user.followings
    @followposts = @posts.where(user_id: @followusers)
  end

  def create
     @user = User.new(user_new_params)
    if @user.save
      # 保存の成功をここで扱う。
      @user.send_activation_email
      redirect_to confirm_path
    else
      render 'new'
    end
  end

  def confirm

  end
  def send_account_mail_new
    @user=User.new
  end
  def send_account_mail
    @user=User.find_by(email: params[:user][:email])
    if @user.activated?
      flash[:danger]="すでにアカウントが有効化されています"
      redirect_to help_path
    else
      @user.send_activation_email
      redirect_to confirm_path
    end
  end
  def likes
    @user=User.find(params[:id])
    @likes=@user.likes.paginate(page: params[:page], per_page: 10)
    # likepages=Post.joins(:likes).paginate(page: params[:page], per_page: 10)
    # @likes=likepages.order("created_at: desc")
  end
  def edit
    @user = User.find(params[:id])
  end

  def update
    @user = User.find(params[:id])
    if @user.update_attributes(user_edit_params)
      # 更新に成功した場合を扱う。
       flash[:success] = "ユーザー情報を変更しました"
      redirect_to @user
    else
      render 'edit'
    end
  end

  def destroy
    User.find(params[:id]).destroy
    flash[:success] = "ユーザーを削除しました"
    redirect_to users_url
  end

  def following
    @user  = User.find(params[:id])
    @users = @user.followings
  end

  def followers
    @user  = User.find(params[:id])
    @users = @user.followers

  end

  private

  def user_new_params
  params.require(:user).permit(:name, :email,:password,:password_confirmation)
  end

  def user_edit_params
    params.require(:user).permit(:name,:password,:image_name)
  end


   # beforeアクション



    # 正しいユーザーかどうか確認
    def correct_user
      @user = User.find(params[:id])
       redirect_to(root_url) unless current_user?(@user)
    end

     # 管理者かどうか確認
    def admin_user
      redirect_to(root_url) unless current_user.admin?
    end

end


(user.rb)

class User < ApplicationRecord
  has_many :posts, dependent: :destroy
  has_many :likes, dependent: :destroy
  has_many :following_relationships, foreign_key: "follower_id", class_name: "Relationship", dependent: :destroy
  has_many :followings, through: :following_relationships
  has_many :follower_relationships, foreign_key: "following_id", class_name: "Relationship", dependent: :destroy
  has_many :followers, through: :follower_relationships
  mount_uploader :image_name, PictureUploader

  # rememberメソッドをUserモデルに追加する
  # attr_accessor=(テーブルのカラム=オブジェクトの属性)をクラスの中で定義しているイメージ。
  attr_accessor :remember_token, :activation_token, :reset_token
   # メールアドレスを小文字にする
  before_save   :downcase_email
  before_create :create_activation_digest
  after_find :create_activation_digest, on: :send_account_mail



  # 名前のバリデーション設定 空をなくす・文字数を50文字以内にする
  validates :name ,presence:true ,length:{maximum:50}

  # メールアドレスのバリデーション設定 空をなくす・文字数を255文字以内にする・重複をなくす・大文字小文字を区別しない
   VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, length: { maximum: 255 },format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false }


  # パスワードのバリデーション設定 空をなくす・文字数を6文字以上にする
  # 半角アルファベット(大文字・小文字・数値)
   has_secure_password
  VALID_PASSWORD_REGAX=/\A[a-zA-Z0-9]+\z/
  validates :password, presence: true, length: { minimum: 6 }, allow_nil: true,format:{with: VALID_PASSWORD_REGAX}
  validate  :picture_size


  # 渡された文字列のハッシュ値を返す
  def User.digest(string)
    cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                                  BCrypt::Engine.cost
    BCrypt::Password.create(string, cost: cost)
  end

  # ランダムなトークンを返す
  def User.new_token
    SecureRandom.urlsafe_base64
  end

  # 永続セッションのためにユーザーをデータベースに記憶する
  def remember
    self.remember_token = User.new_token
    update_attribute(:remember_digest, User.digest(remember_token))
  end

  # トークンがダイジェストと一致したらtrueを返す
  def authenticated?(attribute, token)
    digest = send("#{attribute}_digest")
    return false if digest.nil?
    BCrypt::Password.new(digest).is_password?(token)
  end


  # ユーザーのログイン情報を破棄する
  def forget
    update_attribute(:remember_digest, nil)
  end

 # アカウントを有効にする
  def activate
    update_columns(activated: true, activated_at: Time.zone.now)

  end

  # 有効化用のメールを送信する
  def send_activation_email
    UserMailer.account_activation(self).deliver_now
  end

  # パスワード再設定の属性を設定する
  def create_reset_digest
    self.reset_token = User.new_token
    update_attribute(:reset_digest,  User.digest(reset_token))
    update_attribute(:reset_sent_at, Time.zone.now)
  end

  # パスワード再設定のメールを送信する
  def send_password_reset_email
    UserMailer.password_reset(self).deliver_now
  end

   # パスワード再設定の期限(2時間以内)が切れている場合はtrueを返す
  def password_reset_expired?
    reset_sent_at < 2.hours.ago
  end

  #フォローしているか確かめる
  def following?(other_user)
    following_relationships.find_by(following_id: other_user.id)
  end

  #フォローする
  def follow!(other_user)
    following_relationships.create!(following_id: other_user.id)
  end

  #フォローを外す
  def unfollow!(other_user)
    following_relationships.find_by(following_id: other_user.id).destroy
  end

private

    # アップロードされた画像のサイズをバリデーションする
    def picture_size
      if image_name.size > 5.gigabytes
        errors.add(:image_name, "5GB以内にしてください")
      end
    end

    # メールアドレスをすべて小文字にする
    def downcase_email
      self.email = email.downcase
    end


    # 有効化トークンとダイジェストを作成および代入する
    def create_activation_digest
      self.activation_token = User.new_token
      self.activation_digest = User.digest(activation_token)

    end


end


after_find :create_activation_digest, on: :send_account_mailは有効化メールを再送信するときに使っている物です。
どこを変えていいかわからず、質問しました。
よろしくお願いいたします

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

after_findを消し
before_save   :create_activation_digest, on: [ :create, :send_account_mail ]
とする事で解決しました

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.63%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる