Ruby on Rails: チャットメッセージ実装(フォームから投稿・保存まで)...chapter18-1
①チャットメッセージモデルを作成
$rails g model chat_message
↓
https://gyazo.com/249510f902ab1ea526b27c5f2c82282f
先ほど作成したマイグレーションファイルを編集します。
メッセージ(messageカラム)はtext型で作成し、次の画像のみでも投稿できるようにしたいので、オプションは特につけません。
画像(imageカラム)はstring型で作成。メッセージ同様、メッセージだけでも投稿できるようにしたいので、オプションは特につけません。
ユーザー(user)をidで管理したいので、user_idを自動的に生成してくれるreferencesを使用しました。referencesを使うことによってforeign_keyが使用できるようになったのでtrueとして外部キー制約を使えるようにします。
これでメッセージを送った時に、ユーザーの情報(idやアイコン、ニックネームなど)が使用できるようになります。
チャットグループ(chat_group)をidごとに管理します。
これでチャットグループごとにメッセージが管理できるようになります。
ユーザー(user)同様にreferencesを使用し、chat_group_idを自動生成。
外部キー制約を使用するためにforeign_keyをtrue。
設定が終わったので、マイグレーションを実行します。
$rails db:migrate
↓
https://gyazo.com/27915e30907f4bf12466282fa147b31d
③modelの編集
chat_message、user、chat_groupの各モデルを編集します。
それぞれの関係図:
https://gyazo.com/43848817a55b81b3507577d42885536b
一人のユーザーは沢山のグループを持つことができ、沢山のメッセージを書き込むことができます。
chat_message.rb
上の図の通り、一人の人が沢山のメッセージを書き込めるので、userモデルはbelongs_toを使用。
また、チャットグループも同様で、1つのチャットグループは沢山のメッセージを持っているのでチャットグループの関係性はbelongs_to。
chat_group.rb
チャットグループは沢山のメッセージを持てるので、chat_messagesはhas_many。
また、dependentオプションでdestroyを設定することで、チャットグループを削除された時にメッセージも削除されます。
user.rb
userモデルでもチャットグループと同様に1人のユーザーは沢山のチャットで沢山のメッセージを書き込めるのでchat_messageモデルとの関係性はhas_many。
また、dependentオプションでdestroyを設定することでユーザーを削除した時にメッセージも削除されます。
dependent: :destroyの使い方
▶︎ https://dorarep.page/articles/rails-dependent
④チャットメッセージコントローラーを作成
$rails controller chat_messages
↓
https://gyazo.com/66193b134aada78b1d3e1103315d83e0
⑤ルーティングを設定
routes.rb
chat_groupsと紐づけたいのでchat_messagesをネストしました。
また、メッセージページの表示、メッセージの作成、チャットグループを削除をできるようにしたいのでonlyメソッドを使用しindex, create, destroyの3つのアクションを追加できるようにしました。
このdestroyはチャットグループを削除したときに、このアクションがなければエラーが起こります。
理由としては、チャットグループを削除したのにメッセージが残っていると混乱が起きるためです。
⑥indexアクションをchat_messages_controllerへ追加
⑦index.html.erbを作成
app/views/chat_messages/index.html.erbを作成します。
⑧チャットグループ詳細ページからチャットページへのリンクを作成
$rails routes
https://gyazo.com/e0cbfeff734d704d26275c70eef99f98
/chat_groups/:chat_group_id/chat_messages(.:format)
がチャットメッセージのpathなので。。。
↓
@chat_group.idでchat_groups_controller.rbのshowアクションで取得したチャットグループ情報のidを取得しています。
⑨遷移できているか確認
↓
遷移できるようになりました。
⑩コントローラーのindexアクションの処理内容を設定
app/controllers/chat_messages_controller.rb
各チャットグループ情報をビューで使えるように編集します。
①①index.html.erbを編集(チャットグループへ戻るリンクを作成)
チャットメッセージページを作成します。
link_toメソッドでチャットグループへ戻れるようにリンクを作成しました。
メッセージ表示と投稿フォームを仮置きしています。
↓
表示内容:
https://gyazo.com/2c24e1dc6141ad40b4a49f983628bda9
①②Carrierwaveを使用して、画像を保存できるようにする
app/models/chat_message.rb
ユーザーアイコンやチャットグループアイコンの時に、Carrierwaveのgemはインストールして使えるようにしてあるので、modelに設定するところから始めます。
mount_uploaderでimageカラムを指定しています。
Carrierwaveについて
▶︎ https://qiita.com/nekotanku/items/5da43600f35eada64eac
①③コントローラー編集
投稿したフォームを保存できるようにcreateアクションとストロングパラメーターを作成し、処理内容をコードしていきます。
https://gyazo.com/7234c5d7d9159ba9693db1fd0bc9ef9d
createアクション
@coversations = ChatMessage.new(messages_params)でインスタンスを生成し、インスタンス変数(@conversations)へ代入。
ストロングパラメーターの内容
params.require(:chat_message).permit(:message, :image, :chat_group_id).merge(user_id: current_user.id)
params
送られてきたメッセージを受け取ります。
require(:chat_message)
送られてきた情報をモデルと紐付けます(今回はchat_messageモデルを使用してメッセージを保存します)。
permit(:message, :image, :chat_group_id)
permitで保存許可したい内容を記述します。
merge(user_id: current_user.id)
permitで許可されなかった情報を保存できるようにします。
ストロングパラメーターについて
▶︎ https://qiita.com/ozackiee/items/f100fd51f4839b3fdca8
①④font-awesome-railsをインストール、使用できるようにする
Font Awesomeで用意されているアイコンを使用したいのでfont-awesome-railsをインストールします。
↓
$bundle install
↓
app/assets/stylesheets/application.scss
これで使用できるようになりました。
▶︎ https://pikawaka.com/rails/font_awesome_rails
🚨 font-awesome-railsは最新版font-awesome5には対応していないみたいです。
font-awesomeのversion5の一部のアイコンが表示されないので、対応させたい場合はfont-awesome-sassをインストールします。
↓
$bundle install
↓
app/assets/stylesheets/application.scss
※絶対この順番にしてください。
入れ替えてしまうとアイコンが表示されなくなります。
↓
$brew install yarn
※yarnをインストールをしていない場合はインストールします
Homebrewのこと。
デフォルトでは利用できない便利なツールをインストールしたりアンインストールしたりを管理するツールのこと。
macOSのためにあるツールです。
Homebrewについて
▶︎ https://qiita.com/TAByasu/items/47c6cfbeeafad39eda07
yarn
Node.js(JavaScript)のパッケージマネージャのこと。
パッケージマネージャとは、コンピュータに何のソフトウェアがインストールされたかを記録し、新しいソフトウェアのインストール・新しいバージョンへのソフトウェアの更新・以前インストールしたソフトウェアの削除を容易に行えるようにするプログラム。
yarnについて
パッケージマネージャについて
font-awesome(version5)はフロントエンド開発との連携機能が更に強化されて、手軽にJavaScriptのバンドルにフォントを埋め込むことができるようになっています。
font-awesome(v5)について
▶︎ https://qiita.com/riversun/items/4faa56ac40071f638313
yarnをインストールしたら、サーバーを再起動($rails s)
これでfontawesome(v5)が使えるようになりました。
①⑤index.html.erbを編集(投稿フォームを作成、保存)
https://gyazo.com/00118a1f84903b61cc7e57270259d036
投稿フォームから画像とメッセージが保存できるか確かめます。
注意しなければならないのは、
・text_field_tagのchat_message[chat_group_id]
・file_fieldのname: 'chat_message[image]'
・text_areaのname: 'chat_message[message]'
です。
これがparamsとして送られると、
:chat_message => {:chat_group_id => "〇〇", :image => "〇〇", :message => "〇〇" }
とハッシュ構造されて送られます。
↓
実際に保存できるか確かめます。
https://gyazo.com/87fc9036ca4d4723c6e8fe7b0354446c
画像とメッセージを投稿してみます。
↓
これで保存できるようになりました。
今回の実装で苦労したのは、フォームから投稿する時にchat_group_idは保存できているのに、メッセージと画像がparamsとして送られているのに保存できずに時間がかかったことです😅
途中でname属性でハッシュさせたらどうだろうと気づくことができました。
name属性の使い方の勉強になりました。
次回はチャットメッセージの実装の続きを書こうと思っています。
以上です。