ユーザー情報と記事の紐付けしたあと保存ができない!涙「解決への道のり」Ruby on Rails

Hey guys!!
ユーザー情報と記事の紐付け後につまった!!
今思えばなぜあんなことをしてしまっていたのか。。

ログイン機能が搭載されているgem Deviseを取り入れて、ArticleのDBにuser_idを追加したことを前提に話をすすめる。
ちなみにrails5を使用しています。

それぞれのmodelにhas_manybelongs_to で紐付けした。

models/user.rb

class User < ApplicationRecord 

  has_many :articles
  
  validates :name, presence: true
  validates :email, presence: true, uniqueness: true
  devise :database_authenticatable, :registerable,
              :recoverable, :rememberable, :trackable, :validatable,
              :omniauthable
end

models/article.rb

class Article < ApplicationRecord 

  belongs_to :user

  validates :title, presence: true
  validates :content, presence: true, length: { maximum: 140 } 
  validates :user_id, presence: true
end

これは特に問題なさそうだ。

そして今回の問題がcontrollerのcreateアクションの部分だ。

class ArticlesController < ApplicationController
  
  def create
    @article = Article.new
    @article.title = params[:article][:title]
    @article.content = params[:article][:content]
    @article.save
    redirect_to root_path
  end

試しに記事を投稿してみよう…

..!?

更新したようにみえたけど、DBに保存されていない…

saveをした時にデータがちゃんとあるか確認するために @article.saveの直後にraise @article.inspectを記述して記事を更新。
もちろんRuntime Errorがブラウザ上表示されるがその中身をみるとuser_idとidがnilだ。

rails consoleで確認。

$ @article = Article.new
$ @article.title = "title-test"
$ @article.content = "content-test"
$ @article.save

=> false  

なるほど。 idが足りないからなのか? 検証してみよう。

$ @article = Article.new
$ @article.title = "title-test"
$ @article.content = "content-test"
$ @article.id = 1
$ @article.save

=> false  

ふむふむ。user_idで検証してみよう。

$ @article = Article.new
$ @article.title = "title-test"
$ @article.content = "content-test"
$ @article.user_id = 1
$ @article.save

=> true

お!user_idがあればsaveできるんだな!! user_idをcurrent_userヘルパーメソッド(Deviseにデフォで搭載)とイコールにすれば保存ができそう。

class ArticlesController < ApplicationController

 before_action :authenticate_user!    #追加(これを記述しないとcurrent_userが使えない!!)
  
  def create
    @article = Article.new
    @article.user_id = current_user  #追加
    @article.title = params[:article][:title]
    @article.content = params[:article][:content]
    @article.save
    redirect_to root_path
  end

よし、これで上手くいくはずだ。記事を投稿してみよう。

…えーーー、なんで保存されてないんだーーー涙涙

stack overflowで"rails can’t save data"みたいな感じで検索し、でてきた記事がこれ

ruby - Troubleshooting: Rails can't save to database in production? - Stack Overflow

save!っていうメソッドを使ってみたらどうだろうか?とのこと。
何か手がかりが掴めそうだ

よし、やってみっか!

class ArticlesController < ApplicationController

 before_action :authenticate_user!   
  
  def create
    @article = Article.new
    @article.user_id = current_user  
    @article.title = params[:article][:title]
    @article.content = params[:article][:content]
    @article.save!   #変更
    redirect_to root_path
  end

おやおや?

Validation failed: User must exist, User can’t be blank ってブラウザで言われた。

ははーん、答えがみえてきたぞ。
念のために"Validation failed: User must exist, User can’t be blank"をコピペでググったらstack overflowに行き着いた。

ruby on rails - Validation failed: User can't be blank - Stack Overflow

はい、やっぱり上記の記事と答えが一緒でした!

class ArticlesController < ApplicationController

 before_action :authenticate_user!   
  
  def create
    @article = Article.new
    @article.user = current_user   #変更  
    @article.title = params[:article][:title]
    @article.content = params[:article][:content]
    @article.save
    redirect_to root_path
  end

これでやっと記事が保存できた!!

今回の反省点は二つあった。
一つ目はuser_idがnilだったので保存ができなかったという考えに取り憑かれてuser_idに絞って考えてしまっていたこと。
もう少し視野を広げていたら、そもそもuserがないって早く気付いていたかもしれなかったですね。汗汗

そして二つ目はstack overflowの記事でポイントが低いものはあてにならないと思いスルーしていたことである。
上記で取り上げた2つの記事は両方共ポイントが少なかったが解決に導いてくれた。
ポイントが多い記事がないかついつい探してしまいがちだが、初心者の私にとってはポイントが低い記事も知識の宝庫であることに気付かされた。
これからはポイント数をあまり気にせずに、stack overflowを活用していきたいと思います。。

see you!!