Rails 6.0でアプリを開発 基本の流れ⑫ 記事投稿の設定
今回はユーザーが記事を投稿する機能実装のメモ
実現したいこと
userが短い記事、画像、および動画を投稿できるようにする
1)Postモデルの生成
①Postモデルが持つ属性は
- 実現したいこと
- 1)Postモデルの生成
- 2)バリデーションの追加
- 3)記事とユーザーを紐づける
- 4)2)-①のset upメソッドを修正
- 5)記事の順序付けを行う
- 6)ユーザー破棄で関連記事も破棄されるようにする
- 7)ここまでで記事をいくつか作成している場合リセット
- 8)Postコントローラーの作成
- 9)記事を表示するパーシャルを作成(1つの記事)
- 10)記事のインスタンス変数を定義
- 11)showページに記事を表示
- 12)サンプルデータに記事を追加
- 13)サンプルデータを再度作成
- 14)記事にスタイルを与える
- 15)プロフ画面の記事に対する統合テスト
- 16)Postリソースのルーティング設定
- 17)アクセス制御の設定
- 18)記事用のフォームを生成
- 19)feedメソッドの作成
- 20)記事の削除
- 21)feed画面の記事をテストする
- 22)画像を投稿する
- 参考にさせていただいたサイト
content(text)
user_id(integer)
created_at(datetime)
updated_at(datetime)
②モデルの生成
$ rails g model Post content:text user:references
③インデックスが付与されたMicropostのマイグレーション
※インデックスと外部キー参照付きのuser_idカラムが追加、また[:user_id, :created_at]と1つの配列に入れることで両方のキーを同時に扱う複合インデックスを作成
※user:referencesでbelongs_to:userが追加される
$ rails db:migrate
2)バリデーションの追加
①記事の有効性に対するテスト
②user_idに対する検証
③記事のバリデーションに対するテスト
④③に対してのバリデーション
3)記事とユーザーを紐づける
- belongs_toはすでに自動生成済み。
- has_manyをUserモデル側に設定
※userは複数のpostを持ち、postは一人のuserを持つ
4)2)-①のset upメソッドを修正
new → buildへ(buildはuserに紐づいた新しいPostオブジェクトを返す)
5)記事の順序付けを行う
①テストを記述
②記事のfixtureの作成
③記事を順序付ける(新しいもの順)
- default_scopeメソッド=DBから要素を取得した際のデフォルトの順序を指定するメソッド
- DESC=降順
- 記述はラムダ式
6)ユーザー破棄で関連記事も破棄されるようにする
①記事がその所有者と一緒に破棄されることを保証する
②破棄されるかモデルのテストでチェック
7)ここまでで記事をいくつか作成している場合リセット
$ rails db:migrate:reset
$ rails db:seed
8)Postコントローラーの作成
$ rails g controller Posts
9)記事を表示するパーシャルを作成(1つの記事)
10)記事のインスタンス変数を定義
paginateを使用する
11)showページに記事を表示
順序が必要なのでolタグを使用
12)サンプルデータに記事を追加
13)サンプルデータを再度作成
$ rails db:migrate:reset
$ rails db:seed
14)記事にスタイルを与える
15)プロフ画面の記事に対する統合テスト
①テストの作成
$ rails g integration_test users_profile
②記事のfixtureをユーザーに関連付ける
③ユーザーのプロフ画面に対するテスト
※ここでテストを実行するとターミナルで下記のような文言
To automatically update from positional arguments to keyword arguments,
install rubocop-faker and run:
rubocop \
--require rubocop-faker \
--only Faker/DeprecatedArguments \
--auto-correct
こちらのサイトを参考にさせていただきgemをインストール
上記消えないので、ターミナルの指示通り
$ gem i rubocop-faker
を実行
でも消えないので、指示通りに
$rubocop --require rubocop-faker --only Faker/DeprecatedArguments --auto-correct
を実行
ターミナルが動き出し自動修正?
確かに自動的に変更されている!!
もう一度テストを実行すると再度表示が出てくる。表示を見ると
Passing `word_count` with the 1st argument of `sentence` is deprecated. Use keyword argument like `sentence(word_count: ...)` instead.
一応もう一度
$rubocop --require rubocop-faker --only Faker/DeprecatedArguments --auto-correct
を実行
違反は何もないみたい。
今回使っているposts.yml内にLorem.sentenceがあるので、ここもseed同様変更
その後テストを実行するとメッセージは出ずGreenに!!
16)Postリソースのルーティング設定
記事は主にプロフページとトップページのコントローラーを実行されるのでnewやeditアクションは不要。createとdestroyがあればよい
17)アクセス制御の設定
関連付けられたユーザーを通して記事にアクセスするのでcreate、destroyアクションはログイン済みであること
①Postコントローラーの認可テスト
②logged_in_userメソッドをApplicationコントローラーに移動。ログイン要求のメソッドはPostコントローラーでも必要になるのでどこからでも使えるApplicationコントローラーにUserコントローラーから移動。
※userコントローラーのlogged_in_userは削除
③createとdestroyアクションに対して認可を追加
18)記事用のフォームを生成
micropost/newページを使わずにホーム画面に置く
①Postコントローラーのcreateアクションの設定
※ストロングパラメータも設定
②ホームにPostの投稿フォームを追加
③サイドバーで表示するユーザー情報のパーシャル
④記事投稿用のパーシャル
⑤トップページ画面に記事のインスタンス変数を置く
※フォームをトップページに置くため
⑥Userオブジェクト以外でも動作するようにerror_messagesパーシャルを更新
⑦ユーザー登録時、ユーザー編集時、パスワード再設定時のエラー表示を更新
※⑥による変更で2つのページを更新
※ユーザー登録時とユーザー編集時はパーシャルにしているのでパーシャルを編集
19)feedメソッドの作成
全てのユーザーがfeedを持つのでUserモデルに作成
①現在ログインしているユーザーの記事をすべて取得してくる
"user_id = ?" →SQLクエリに代入する前にidがエスケープされSQLインジェクションと呼ばれセキュリティホールを避ける。
(SQLに変数を代入する場合、常にエスケープする癖をつける)
②homeアクションにフィードのインスタンス変数を追加
③ステータスフィードのパーシャルを作成
※railsは対応する名前のパーシャルを渡されたリソースのディレクトリから探しに行ける。
@feed_item → Micropostのパーシャル
@micropost → Micropostのパーシャル
@user → Userのパーシャル
④トップページにステータスフィードを追加
⑤createアクションに空の@feed_itemsのインスタンス変数を追加
※投稿が失敗しても崩れないようにするため
20)記事の削除
投稿したユーザーのみ削除リンクが動作するようにする
①記事のパーシャルに削除リンクを追加
②Postコントローラーにdestroyアクションを定義
③Postコントローラーにbeforeコールバックを設定
current_userのみがdestroyできる
request.refererメソッド
フレンドリーフォーワーディングのrequest.urlに似ていて一つ前のurlを返す
(=redirect_back(fallback_location: root_url)
21)feed画面の記事をテストする
①記事用fixtureに別のユーザーに所属している記事を追加
②間違ったユーザーによる記事削除に対するテスト
③統合テスト
ⅰ)統合テストの生成
$ rails g integration_test posts_interface
ⅱ)UIに対する統合テスト
ⅲ)再度バーで記事の投稿数をテストするためのテンプレ
22)画像を投稿する
Postモデルに複数の画像ファイルを紐づける形で
・・画像フォーマットのバリデーション
・・画像に対するバリデーション
・・動画の投稿
・・テスト
今回はとても長いので画像投稿は別途まとめる(^^)/
参考にさせていただいたサイト
第13章 ユーザーのマイクロポスト - Railsチュートリアル