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

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

ただいまの
回答率

88.77%

多対多で削除ができません。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 925

ma5toy

score 15

前提・実現したいこと

記事を削除した際に、多対多であるタグ情報も一緒に削除できるようにしたいです。
他のサイトを見てみても、同じような記述で出来ているようですが。。。
どなたかご教授いただければと思います。
宜しくお願いいたします。

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

Processing by Users::ArticlesController#destroy as HTML
  Parameters: {"authenticity_token"=>"9NYI/LWmMSLANHDVSwlxx+THFq4aiEf6UIBPOlfHL2g7s8x+WyeuF5aShwLvCn0OC7+rAF3HWJiu6zBhacQ+og==", "id"=>"47"}
  Article Load (0.4ms)  SELECT  `articles`.* FROM `articles` WHERE `articles`.`id` = 47 LIMIT 1
  ↳ app/controllers/users/articles_controller.rb:50
   (0.1ms)  BEGIN
  ↳ app/controllers/users/articles_controller.rb:51
  Impression Destroy (0.3ms)  DELETE FROM `impressions` WHERE `impressions`.`impressionable_id` = 47 AND `impressions`.`impressionable_type` = 'Article'
  ↳ app/controllers/users/articles_controller.rb:51
  TagMap Load (0.4ms)  SELECT `tag_maps`.* FROM `tag_maps` WHERE `tag_maps`.`article_id` = 47
  ↳ app/controllers/users/articles_controller.rb:51
  TagMap Destroy (0.3ms)  DELETE FROM `tag_maps` WHERE `tag_maps`.`article_id` = 47 AND `tag_maps`.`tag_id` = 1
  ↳ app/controllers/users/articles_controller.rb:51
  TagMap Destroy (0.3ms)  DELETE FROM `tag_maps` WHERE `tag_maps`.`article_id` = 47 AND `tag_maps`.`tag_id` = 2
  ↳ app/controllers/users/articles_controller.rb:51
  TagMap Destroy (0.3ms)  DELETE FROM `tag_maps` WHERE `tag_maps`.`article_id` = 47 AND `tag_maps`.`tag_id` = 3
  ↳ app/controllers/users/articles_controller.rb:51
  Article Destroy (0.7ms)  DELETE FROM `articles` WHERE `articles`.`id` = 47
  ↳ app/controllers/users/articles_controller.rb:51
  User Load (0.3ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
  ↳ app/controllers/users/articles_controller.rb:51
   (5.6ms)  ROLLBACK
  ↳ app/controllers/users/articles_controller.rb:51
Completed 500 Internal Server Error in 34ms (ActiveRecord: 9.3ms)



TypeError (nil is not a symbol nor a string):

app/controllers/users/articles_controller.rb:51:in `destroy'

該当のソースコード

/tag.rb

class Tag < ApplicationRecord
  validates :tag_name, presence: true, length: {maximum:99}
  has_many :tag_maps, dependent: :destroy
  has_many :articles, through: :tag_maps
end
/article.rb

class Article < ApplicationRecord
  mount_uploader :article_thumbnail, ArticleThumbnailUploader
  is_impressionable counter_cache: true

  belongs_to :user, dependent: :destroy
  belongs_to :category
  belongs_to :sub_category
  belongs_to :user, optional: true
  has_many :tag_maps, dependent: :destroy
  has_many :tags, through: :tag_maps
  accepts_nested_attributes_for :tag_maps, allow_destroy: true
/tag_map.rb

class TagMap < ApplicationRecord
  belongs_to :article
  belongs_to :tag
end
スキーマ
create_table "articles", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
  t.text "article_title", null: false
  t.text "article_content", null: false
  t.integer "user_id", null: false
  t.integer "category_id"
  t.integer "sub_category_id"
  t.string "article_thumbnail"
  t.integer "impressions_count", default: 0
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end
コントローラー
class Users::ArticlesController < ApplicationController
  before_action :require_login
  before_action :logedin_admin?

  def show
    @article = Article.find(params[:id])
  end

  def new
    @article = Article.new
  end

  def edit
    @article = Article.find(params[:id])
  end

  def create
    @article = Article.new(article_params)
    respond_to do |format|
      begin
        ActiveRecord::Base.transaction do
          @article.save!
        end
        # 正常処理
        format.html { redirect_to articles_path }
        format.json { render :index, location: @article }
      rescue ActiveRecord::RecordInvalid
        # バリデーション処理
        @article.valid?
        format.html { render :new }
        format.json { render json: @article.errors }
      rescue => e
        Rails.logger.error e
        Rails.logger.error e.backtrace.join("\n")
        Raven.capture_exception(e)
        flash.now[:danger] = "保存に失敗しました"
        format.html { render :new }
      end
    end
  end

  def update
    @article = Article.find(params[:id])
    if @article.update!(article_params)
      redirect_to root_url
    else
      render :edit
    end
  end

  def destroy
    @article = Article.find(params[:id])
    @article.destroy!
    redirect_to users_articles_path
  end

  private

  def article_params
    params.require(:article).permit(:article_title, :article_content, :article_thumbnail, :article_thumbnail_cache, :category_id, :sub_category_id, {:tag_ids => []}, :user_id)
  end

  def logedin_admin?
    redirect_to articles_path unless current_user.admin?
  end

  def set_user

  end
end

試したこと

ActiveRecordでidがないテーブルにデータを保存しようとすると"nil is not a symbol"とか言われる

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

ruby 2.5.2p104 (2018-10-18 revision 65133) [x86_64-linux]
Rails 5.2.1

ここにより詳細な情報を記載してください。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • 退会済みユーザー

    退会済みユーザー

    2019/04/21 17:24

    DBのスキーマ情報や、Users::ArticlesController の中身があれば回答が得られやすいと思います

    キャンセル

  • ma5toy

    2019/04/26 05:03

    遅くなって申し訳ございません!情報追加しました。
    宜しくお願いいたします。。。

    キャンセル

  • odyu

    2019/04/26 12:17

    もう少し細かいログがみたいです。--traceとかで出力できたような
    それで現状のログを見たいのと

    試しに
    has_many :tag_maps # , dependent: :destroy
    これで実行した場合の結果をみたいです。

    ここも気になりますね。
    class Article
    belongs_to :user, dependent: :destroy
    belongs_to :user, optional: true

    キャンセル

回答 1

checkベストアンサー

0

確信は持てないのですが、Articleモデルの

belongs_to :user, dependent: :destroy


を消してみてはいかがでしょうか。
そうすれば削除はできそうな気がします。

また、belongs_to :userは2回出てきているので、どちらかはいらないでしょう。

親userをどうしてもdependent: :destroyしたいということであれば、

belongs_to :user, optional: true, dependent: :destroy


という書き方になると思いますが、こうした場合はarticleを削除できなくなる可能性があがりそうです。

補足

userモデルはarticleから見てoptional: trueなので、おそらく親userなしのarticleが存在しても問題ないと考えられます。(定かではありませんが) 

しかし、userモデルがarticle以外の子モデルをhas_manyしていた場合、そちらのモデルからもoptional: trueが設定されていないと、親userが存在しないことがerror原因になりそうです。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/04/28 01:49

    > belongs_to :user, dependent: :destroy
    を削除しました。無事解決です。
    2つ。。。すみませんミスりました。。

    ありがとうございました!

    キャンセル

  • 2019/04/28 03:14

    解決できたようで何よりです!

    キャンセル

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

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

関連した質問

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