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

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

ただいまの
回答率

87.78%

destroyアクションが反応しない

解決済

回答 1

投稿 編集

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

score 13

前提・実現したいこと

userを削除したいのですが
destroyアクションがうまく機能しません

発生している問題・エラーメッセージ

エラーメッセージが表示されません

該当のソースコード

users_controller

class UsersController < ApplicationController
  include SessionsHelper


  def destroy
    user = User.find(params[:id])
    #binding.pry
    user.destroy
    redirect_to root_url
  end

drinks/index.html.erb

<%= link_to "退会する", user_path(current_user),method: :delete %>

current_userは自分で定義したヘルパーメソッドです

sessions_helper.rb

  # 現在ログインしているユーザーの情報を取得
  def current_user
    # DBの問い合わせの数を可能な限り小さくしたい
    # logged_in?メソッドでも使われてるし、、、
    if user_id = session[:user_id]
      # セッションがある場合
      # すなわちログインしてる時のみ

      # sessionにアクセスした結果を変数に
      # 入れておいてあとで使いまわした方が
      # 早くなる
      @current_user ||= User.find_by(id: user_id)
      # find_byでデータベースにクエリを投げる
      # ブラウザのセッションにあるuser_idをもとにUser定義

      # find_byの実行結果をインスタンス変数に保存する
      # ことで、1リクエスト内におけるデータベースへの
      # 問い合わせは最初の一回だけになり、 
      # 以後の呼び出しではインスタンス変数の結果を
      # 再利用する

      # すでに@current_userが存在する場合って何?
      # 一回current_userを実行したら、
      # @current_userがあるのでそれを使ってね

      # sessionのuser_idがあるということは
      # 既にログインしてるといてDBにユーザーの情報があるはず。
      # だからsessionのuser_idをDBでfind_byかければいい
    elsif  (user_id = cookies.signed[:user_id])
      # sessionが張られてなかったらcookiesにあるかも
      user = User.find_by(id: user_id)
      if user && user.authenticated?(cookies[:remember_token])
        # nilガード
        # クッキーのuser_idとremember_tokenが一致してる
        log_in user
        @current_user = user
      end
    end
  end

user.rb

class User < ApplicationRecord
  attr_accessor :remember_token
  # remember_tokenというメソッドを作成
  # password,password_comfirmationみたいな
  # 変数のように扱える
  # u.remember_token的なことができる
  has_many :drinks, dependent: :delete_all
  before_save  { self.email = email.downcase }
  has_secure_password
  validates :nickname,  presence: true, length: { maximum: 50 }
  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 }
  validates :password, presence: true, length: { minimum: 6 },allow_nil: true
  # ユーザー更新時に空のパスワードでも大丈夫
  # has_secure_passwordの方でpasswordの存在性を検証するから大丈夫



  # 渡された文字列のハッシュ値を返す
  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

  # 永続的にログインするためにトークンをDBに保存
  def remember
    self.remember_token = User.new_token
    # 何のトークンか分かりやすいから
    # remember_tokenって名前を作った
    update_attribute(:remember_digest,User.digest(remember_token))
    # ハッシュ化したトークンをremember_digestに保存
  end

  # 渡されたトークンがダイジェストと一致したらtrue
  # を返す
  def authenticated?(remember_token)
    return false if remember_digest.nil?
    # 二種類のブラウザを使用してログアウトした場合
    # cookiesのremember_tokenはあるけど、
    # サーバー側でremember_digestをnilにしてるから
    # nilに対して.is_password?とかやるとfor nil classエラーが起きちゃう
    # remember_digestがnilの場合はfalseを返して、処理を止める

    # 後置if文に当てはまる条件があれば処理を止めて!
    # って場合はreturnとかで明示的に書くとif ~ else ~ end 
    # とか書かなくて済む
    BCrypt::Password.new(remember_digest).is_password?(remember_token)
  end

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

Drink.rb

class Drink < ApplicationRecord
  belongs_to :user
  with_options presence: true do
    validates :name
    validates :explain
  end
end

:20201116073717_create_users.rb

class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :nickname
      t.string :email
      t.string :password_digest

      t.timestamps
    end
  end
end

/20201118162753_create_drinks.rb

class CreateDrinks < ActiveRecord::Migration[6.0]
  def change
    create_table :drinks do |t|
      t.string :name
      t.integer :price
      t.text :explain
      t.references :user,null: false,foreign_key: true 
      t.timestamps
    end
  end
end

routes.rb

Rails.application.routes.draw do
  root to: 'drinks#index'
  get    '/login',   to: 'sessions#new'
  post   '/login',   to: 'sessions#create'
  delete '/logout',  to: 'sessions#destroy'
  resources :users
  resources :drinks, only: [:index,:new,:show,:create,:destroy]
end

退会リンクをusers/showに移動しました

エラーも起きていませんし、@userの定義もしっかりできていて、@user.nameとかやってもしっかり表示できているので、リンクの指定はあってると思います

このログを見るとリンクを踏んだ後にrootに戻ってるように見えます

補足情報(FW/ツールのバージョンなど)

ruby 2.6.5
rails 6.0.3

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • divclass123

    2020/11/28 20:53

    解決できました、、、!原因はbefore_actionで何故かdestroyをフィルタリングしてたことが原因でした、、、、

    キャンセル

  • tomtomtomtom

    2020/11/29 01:42

    ご解決おめでとうございます^^
    力になれず申し訳有りませんでした。

    キャンセル

  • divclass123

    2020/11/30 17:25

    いえいえとんでも無いです、助けて頂いてありがとうございました、、!
    質問欄にbefore_actionを記述しておくべきでした。

    キャンセル

回答 1

check解決した方法

0

 before_action :logged_in_user, only: [:index,:edit,:update,:destroy]
  before_action :correct_user, only: [:edit, :update,:destroy]
    def correct_user
      redirect_to(root_url) unless current_user?(@user)
    end
  def logged_in_user
    unless logged_in?
      store_location
      # ユーザーがいきたがってたページを記憶
      flash[:danger] = "Please log in"
      redirect_to login_url
    end
  end

<strong>原因はbefore_actionにdestroyを設定してた</strong>
:destroyを外してあげればok

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

同じタグがついた質問を見る