Hey guys!!
ユーザー情報と記事の紐付け後につまった!!
今思えばなぜあんなことをしてしまっていたのか。。
ログイン機能が搭載されているgem Deviseを取り入れて、ArticleのDBにuser_idを追加したことを前提に話をすすめる。
ちなみにrails5を使用しています。
それぞれのmodelにhas_manyとbelongs_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!!