##はじめに
Rails5.0での投稿機能実装ではまったのでメモ
##環境
macOS Catalina
Ruby 2.5.1
Rails 5.0.7.2
PostgreSQL
##困り
form_forでDBにデータを登録しようと思ったが、エラー出てないのにデータ保存されていなかった
##対処した方法
- GUIアプリで確認
- 保存されない原因を確認①(pry-rails)
- ハッシュの二重構造を解消
- 保存されない原因を確認②(メソッドの後ろに"!")
- バリデーションによるエラーを解消
###1. GUIアプリで確認
- PostgreSQLを使用しているので、Posticoをインストール
- GUIアプリでDBが見れるようになったら、もう一度投稿してみる
- GUIアプリ上ではデータが保存されていないはず
▼インストール方法とDBへの接続方法
PostgreSQL:PostgreSQLのデータをGUIでいじる(macOS/Postico)
MySQL:Sequel Proを使ってデータベースを視覚化しよう
▼DB名の調べ方
ターミナルで「psql -l」を実行
実行結果の「app-name_development」が対象のDB名
$ psql -l #PostgreSQLのDBを一覧で表示する
#実行結果
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-------------------------+--------+----------+---------+-------+-------------------
app-name_development | user | UTF8 | C | C |
app-name_test | user | UTF8 | C | C |
postgres | user | UTF8 | C | C |
template0 | user | UTF8 | C | C | =c/user +
| | | | | user=CTc/user
template1 | user | UTF8 | C | C | =c/user +
| | | | | user=CTc/user
(5 rows)
###2. 保存されない原因を確認①(pry-rails)
- pry-railsをインストール
group :development, :test do
gem 'pry-rails'
end
$ bundle install
-
サーバー再起動(Ctrl + C、rails s)
-
データを保存するメソッドに binding.pry
def create
binding.pry #データを保存するメソッドの中に
Post.create(post_params)
end
private
def post_params
params.permit(:content, :image)
end
- もう一度投稿してみる
- 投稿画面は読み込み中になるので、ターミナルでparamsを確認
3: def create
=> 4: binding.pry
5: Post.create(post_params)
6: end
#params と入力
[1] pry(#<PostsController>)> params
=> <ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"zDzgsL3bOIk0QSPOFk7eSOxvqVk18RQ0PW14dC3A7JtsLB9X2pLwvJ41V/f9WeqBDRo4Uz2PKtJDvcT4WpSCRg==", "post"=><ActionController::Parameters {"content"=>"ポストの内容テストテストテスト", "image"=>"test.jpeg"} permitted: false>, "commit"=>"投稿", "controller"=>"posts", "action"=>"create"} permitted: false>
#post_params と入力
[2] pry(#<PostsController>)> post_params
Unpermitted parameters: :utf8, :authenticity_token, :post, :commit
=> <ActionController::Parameters {} permitted: true> #ハッシュの中身が空なので登録できていない
ハッシュである'{}'の中身が空になっているため、
params.permit(:content, :image)では、paramsから該当するキーを取得できていないのが原因
###3. ハッシュの二重構造を解消
def create
Post.create(post_params) #binding.pry は削除
end
private
def post_params
params.require(:post).permit(:content, :image)
#requireメソッドを使って二重構造となっているハッシュを取得
end
- もう一度投稿する
- Posticoで保存されているか確認 ⇒ 保存されていれば完了!
###4. 保存されない原因を確認②(メソッドの後ろに"!")
- 保存されない場合は別の方法で原因を確認
- 保存するメソッドの後ろに!をつける
def create
Post.create!(post_params) #binding.pry は削除 #createの後ろに"!"
end
⇒アソシエーションが組まれている際に、該当の外部キーが入っておらず、バリデーションで弾かれている
###5. バリデーションによるエラーを解消
- optional: trueを記載
class Post < ApplicationRecord
belongs_to :user, optional: true #optional: ture を記載
end
- optional: trueとは、belongs_toの外部キーのnilを許可するというもの
Railsのbelongs_toに指定できるoptional: trueとは?
- 僕の場合はこれで保存できました。
##参考記事
https://teratail.com/questions/121213
https://qiita.com/tanaka7014/items/50a1a953b3f440cbe481