Ruby on Rails: チャットメッセージ実装(自動更新機能まで)...chapter18-2
①タイムゾーンの設定
2020年9月1日みたいな感じで投稿した日にちを表示したいのでタイムゾーンを設定していきます。
config/application.rb
config.time_zone= "Tokyo"
config.active_record.default_timezone= :localを設定します。
↓
$rails s
サーバーを再起動します。
②chat_messages_controller.rbの編集
app/controllers/chat_messages_controller.rb
@messagesにチャットグループでのメッセージを代入します。
③index.html.erbのビューを編集
https://gyazo.com/6781ccd0fa45a0b85d1f9b21fe9567f7
https://gyazo.com/89f484d0508d9edd20bf7de4dd206382
↓
https://gyazo.com/0c6b1342f1c00691713c797fcafa2d7b
https://gyazo.com/7dd81829b992ee348ce8fd6122b89ce6
とりあえずメッセージが投稿されるようになりました。
しかし非同期通信はできていないので、投稿したときに
非同期通信をして部分的更新をして更新速度を上げるのと、2窓してみて自動更新できるようにしていきたいと思います。
④app/controllers/api/chat_messages_controller.rbを作成
$rails g controller api/chat_messages
↓
https://gyazo.com/4eb0e8e76d30d2989d0adf1bbbbc99e1
↓
これでApplicationControllerはApi::ChatMessagesControllerを継承できるようになりました。
これで、このコントローラーへコードしたことはapiを使用したもののみを対応させて動かすことができます。
後でここに投稿した後に投稿されたメッセージが表示されるように処理内容をコードします。
app/views/chat_messages/create.json.jbuilder
app/controllers/chat_messages_controller.rbのcreateアクションでインスタンス変数へ代入したメッセージ情報をjsonへ変換します。
app/views/api/chat_messages/index.json.jbuilder
忘れないようにこちらのjbuilderファイルも作成しておきましょう。
私はこのファイルを作成し忘れていて配列を用意したいのにできず2日悩みました。←慣れていれば、こんなことで悩むことはないと思うのですが😂 (笑)
⑥app/controllers/api/chat_messages_controller.rbを編集
@groupのインスタンスへChatGroupモデルを通してfindメソッドでchat_group_idを探してきて、投稿しているチャットグループの情報を代入します。
@messages = @group.chat_messages.includes(:user).where('id > ?, params[:id]')
params[:id]...これはchat_messages.jsでajaxによって送られてきたidです。
チャットメッセージで最後に投稿されたメッセージのidよりも大きいidのメッセージがないか探してきてインスタンス変数@messagesへ代入します。
includes(:user)はN+1問題の対策のために使用します。
N+1問題を解決する理由としては同じ繰り返し処理を減らしてSQL発行を減らそうという考えです。
このincludesがなければ、「投稿されたメッセージは誰のなの???」とchatmessagesテーブルとusersテーブルの間を行ったり来たりして探すという作業が行われます。
なので投稿されたメッセージ分だけusersテーブルを行き来します。
これは無駄な作業です。
これではメッセージが増えれば増えるほどSQLへの負担が大きくなります。
投稿されたメッセージをまとめてusersテーブルへ探しに行けるのがincludesメソッドです。
https://qiita.com/TsubasaTakagi/items/8c3f4317ad917924b860
そしてrespond_to do |format|~endまででhtmlをjsonへ変換できるようにしておきます。
⑦chat_messages.jsファイルを作成
app/javascript下へchat_messages.jsファイルを作成します。
⑧app/javascript/packs/application.jsを編集
chat_messages.jsファイルを使用できるように↓を追加します。
これでchat_messages.jsファイルを使用できるようになりました。
⑨app/controllers/chat_messages_controller.rbを編集
createメソッドでjsonへ変換できるようにしておきます。
⑩app/javascript/chat_messages.jsを編集
注意することは、⑥でparams[:id]としたこと。
これは$.ajax({ ~ }).done({ ~ data: {id: 〇〇})←この太字にした部分と同じでないといけません。
なのでdata:{last_id: 〇〇}とした場合、⑥はparams[:last_id]とします。
[ 1 ]
https://gyazo.com/99ef582eb08084f5ddb789763fa700c1
[ 2 ]
https://gyazo.com/a48a1d2c55da565e1158f03380732abc
[ 3 ]
https://gyazo.com/5e6ae49f2ca2da5dd68a189d152f501c
[ 1 ]でここでメッセージを投稿した時に、追加するhtmlを作っておきます。
・変数message_idに投稿されたメッセージのidを格納
・変数user_iconにもしユーザーアイコンがあるならばアイコンを、なければデフォルトのアイコンを格納
・変数chat_messageにメッセージがあるなら格納し、なければ入れない。
・変数imageもchat_messageと同様。画像があるかないかによって処理を分けてます。
・変数dateへupdated_atを格納
・変数htmlへ投稿したときの追加内容を格納
[ 2 ]でメッセージ投稿処理をしています。
・e.preventDefault()で投稿ボタンを押すまで処理を待ってくれます。
https://qiita.com/tochiji/items/4e9e64cabc0a1cd7a1ae
・変数formDataへformタグの開始から終了までの処理内容を入れてインスタンス変数を格納
・変数urlにメッセージページのurlを格納
・done(function(data){・・・})でdataは投稿された内容を格納しています。これを結果で返します。
$('form')[0].reset();...これでメッセージを投稿後リセットされます。
https://pikawaka.com/javascript/form-reset
$('#chat-messages-btn').prop('disabled', false);...ボタンが再度有効になります。
https://qiita.com/pugiemonn/items/5db6fb8fd8a303406b17
・変数iへ送ったメッセージが表示されているトップの座標を格納
・$('html, body').animate({scrollTop:i})...animateメソッドを使用しスクロール動作できるようにします。その際、垂直にスクロールしたいのでscrollTopを使用し垂直にスクロールするためのピクセル数を取得します。
https://itsakura.com/jquery-scroll
https://www.sejuku.net/blog/61689
[ 3 ]でメッセージを最新状態に保つための処理をしています。
・変数last_message_idに最新の(最後の)メッセージidを取得。
・if文内容でこのメッセージページと一致した場合にこの中の処理が実行できるようにします。このif文がないと他のチャットグループのメッセージを開いているとエラーがでます。
・変数insertHTMLへ空の変数を定義
・messages.forEach(function(message){})...messagesをforEachで繰り返しし取り出し処理して、この中での処理内容を引数messageへ渡します。
・insertHTML=buildHTML(message);...投稿されたメッセージ結果を格納
・$('.chat-messages__conversations').append(insertHTML);...insertHTMLに格納された処理内容を<div class="chat-messages__conversations">~</div>へ追加。
・setIntervalは一定の処理を繰り返すメソッドです。これで、自動更新機能を実装できます。7000は一定処理を繰り返す時間を設定しています(今回は7000ミリ秒=7秒間隔で処理しています)。
https://techacademy.jp/magazine/5537
[ 1 ]でのreturn htmlに関しては、これをコードしておかないと追加できなくなります。
returnは関数処理した結果を戻り値として返せます。
https://www.javadrive.jp/javascript/function/index4.html
↓
https://gyazo.com/6704d1f3533a3d085fd1db3fd78cfa17
https://gyazo.com/7ef7c0e2efc4a874c12fcf0d6a36028d
非同期機能と自動更新機能を実装しました。
実装時のポイントはconsole.logを使用して処理内容を確認しながら作るってことでしょうか😅(例)console.log(this);)。
以上です。
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属性の使い方の勉強になりました。
次回はチャットメッセージの実装の続きを書こうと思っています。
以上です。
Ruby on Rails: チャットグループの修正...chapter17
エラーが出てしまったので修正しました。
▼ エラー内容及び原因 ▼
(エラー内容→原因)
①チャットグループの詳細画面へ遷移するとエラーが発生
→チャットグループ情報を取得するべきところをユーザーidを取得していた
②カレントユーザーが二重でグループに保存されてしまう
→chat_groups/new.html.erbでform_withでカレントユーザー情報(+グループ追加ユーザー情報)+text_field_tagでカレントユーザーidを送信と二重でカレントユーザー情報を送信していた
▼ 修正後のコード ▼
chat_groups_controller.rb
https://gyazo.com/b3ac396de74f66f970a3962eeb406bbe
・newアクションでcurrent_userを追加したのを削除。
・createアクションでcurrent_user情報を二重で保存しないように chat_group_new.user_ids = current_user.idを削除。
chat_groups/new.html.erb
https://gyazo.com/c95d12cf6fc9619f360ee5d2a47f837f
text_field_tagでカレントユーザー情報を送っていたのを削除しました。
chat_groups/show.html.erb
https://gyazo.com/2fe80805121575e423a7a9e567d01616
if文でチャットメンバー達がアイコンを登録しているかによって条件分岐するように修正。
これで、チャットメンバーの詳細画面へ遷移することができ、かつグループメンバーでチャットグループを作成したユーザーの二重登録をなくすことができました。
次回はチャットグループからメッセージを送る時に自動更新をして最新状態にして置けるように実装していきたいと思います。
以上です。
Ruby on Rails: インクリメンタルサーチと非同期通信...chapter16
今回は非同期通信、インクリメンタルサーチをやりたいと思います。
jQueryを使用します。
jQueryとは
Javascriptを扱いやすくしたものです。
Javascriptで10行くらいかけるものを1,2行で済ませてくれるのがjQueryです。
また、ブラウザによってJavascriptが動かない場合がありますが、jQueryではどのブラウザでも同じ動きをします。
Gemfile
jQueryが使用できるようにgemをインストールします。
↓
$bundle install
↓
app/javascript/users.jsファイル作成
↓
application.js
↓
$rails s
これだけではエラーが出ました。
なので、解決策を検索。
https://qiita.com/masahisa/items/eaacb0c3b82f4a11fc13
$yarn add jquery
↓
config/webpacker/enviroment.js
↓
$rails s
これでエラーがなくなりました。
yarnこれはRailsでいうところのGemみたいな役割をするJavascript版らしいです。
routes.rb
indexアクションのルーティングを追加しました。
users_controller.rb
後ほど検索した結果をkeywordをキーとして受け取るようにします。
なのでparamsで受け取った検索がもし空ならnilで返します。
User.where()でUserモデルを使用し、whereでDBに検索をかけることができます。
検索したいのはnicknameなので"nickname"とします。
また"nickname LIKE?"とすることで"あいまい検索"ができるようになります。
?←これはプレースホルダーというもので、第2引数("%#{params[:keyword]}")を?のところに置き換えることができます。
つまりaaaというユーザーを検索したい時、「a」と入力するだけでaのつくユーザーを探してくれます。
しかし、aがどこについてもいいという検索は避けたいので(abc, bac, cbaなど)、ワイルドカードを使用し検索条件を設定します。
ワイルドカードは_と%があります。
%...0文字以上の任意の文字列
_...任意の1文字
%〇〇とするしてaのつくユーザーを検索します。
aのつく候補として(aaa, abc, bac, cba,aa,ab,ba)がいるとすると、aと入力すると
候補(aaa, cba, aa, ba)が出てきます。これは〇〇aとつくユーザーを検索できます。
次に〇〇%で検索してみます。
候補(aaa, abc, aa, ab)が出てきます。これはa〇〇とつくユーザーを検索できます。
次に_〇〇を試してみます。
候補(aa, ba)が出てきます。つまり○+aを検索できます。
%と違い_(アンダーバー)の数今回は1文字分を検索しているので、cbaは検索から弾かれます。
次に〇〇_を試します。
候補(aa, ab)が出てきます。a+○を検索しています。
今回はaと入力するとa○やa〇〇のように頭文字に検索したものの候補がくるようにしたいので〇〇%にしたいと思います。
https://www.wakhok.ac.jp/biblion/1994/DB/subsection2.4.3.5.html
ログインユーザー(チャット新規作成しているユーザー)が検索されないようにwhere.not()を使いidを検索できないようにします。
そしてインスタンス変数@usersに代入します(検索結果を代入)。
respond_to do |format|~end
ここに記述すると、通常はhtml形式で結果を取得するが他の形式で取得したい場合に指定できます。
チャット新規作成ページへ遷移した時はhtmlで取得したいのでformat.html。
そしてjsonを介してデータ(検索をかけたいユーザー)を取得する時はjsonを使用したいのでformat.jsonとしています。
app/views/users/index.json.jbuilder
index.json.jbuilderファイルを作成します。
今回はjsonを使用したいと思います。
jsonとは"Javascript Object Notation"の略です。
〇〇.json.jbuilderファイルはjson形式を作成しやすくするために作成するファイルです。
このファイルに記述することによってjson形式の文字列のデータを作成することができます。
json.array!
インスタンス変数が複数あるときに使用します。
@usersの中身はユーザー情報が入っています。
例えば、aaaというユーザーの場合
https://gyazo.com/b524ee40f7612abfb59948b5a1ea9bf8
idやnickname、emailなど複数の情報が入っています。
json.キー名 "値"
jsonに変換したい(データ渡したい)のはidとnicknameなので、usersコントローラーで作成したindexアクションの中の処理で作成したインスタンス変数(@users)から繰り返し処理をして|user|一つずつuserを取り出ます。
そしてuser.idとuser.nicknameと記述してidとnicknameを取り出し、json形式でidとnicknameを使用できるようにidとnicknameをキー名として値を渡しています。
https://pikawaka.com/rails/jbuilder(jbuilderの使い方について)
app/views/chat_groups/new.html.erb
全体のコード:
https://gyazo.com/c420b3226691d57a3c0b2af0bf97eb55
検索フォーム部分のコード:
https://gyazo.com/e43b87bc7504d87c3d9199a0a504be0a
検索した結果を
↑部分に表示します。
https://gyazo.com/1a7f6fd9138f820a6cad55766ae69d8e
↓
メンバー追加後:
ここのコードは検索して追加したユーザーが表示されるところです。
このコードが出現したり削除をクリックしたときに消えたりするようにします。
users.js
https://gyazo.com/385393aa49a1d79775ebc02bc07ed207
https://gyazo.com/9e88a345327134d97104af055aa3b903
jQuery(document).ready(function(){〇〇〇〇});の略。
これはHTMLを読み込みが終わったら実行するという意味です。
まず、関数を作成します。
関数とは、ある処理をまとめておけるようなものです。
関数を使用することでコードが見やすくなります。
関数を作成する時は、functionを最初に記述します。
続いてfunctionに任意の関数名を指定します。今回はaddUserにします。
()内に引数をします(引数user)。
ここに引数を指定しておくと、関数を呼び出されてた時に値が渡されている場合にその値を代入してくれます。後ほど、関数を呼び出すコードを記述します。
letは変数を宣言する時に使用します(これは変数ですよと分かりやすくしています)。
letを使用すると変数を再宣言できなくなります。
let a = '初期設定';
a = '再代入可能';
let a = '再宣言不可';
今回は変数htmlをletで宣言しました。
$(〇〇).append(html);で先ほど宣言した変数htmlを〇〇へ追加します。
関数を作成します。
関数名notUserにし、今回は引数はなしなので()のみです。
letを使用し変数を宣言します。
そして、appendメソッドを使用し、ユーザーが見つからない時にid="chat-group-new__member__search"へ追加する関数を作成しておきます。
検索で追加したユーザーを表示するための処理をする関数を作成します。
上記と同様にappendで変数htmlの内容をid="chat-group-new__add__right__js"へ追加します。
https://gyazo.com/9f1db133b1cf2fa1d6ebc393af435825
ユーザーを追加した後に追加したユーザーを登録できるようにinputメソッドにユーザーidを入れて変数htmlに代入します。
そして、変数htmlをid="chat-group-new__add__right__js"へ追加できるように関数を作成します。
追加したユーザーの値を引き渡されるように引数を記述します(userId)。
上記のremoveUserは表示をするだけです。
このinputがないと新規作成ボタンを押した時にデータが保存できません。
$(〇〇).on("keyup",function(){処理内容});
.on()これを使うと様々なイベント処理(マウス操作やキーボード入力、フォームを送信した時、画面をスクロールした時など)をすることができます。
https://www.sejuku.net/blog/38774
今回はkeyupを使用します。
keyupはキーボードを入力した時に発火するように(処理されるように)しています。
何を発火するのかというと、funciton(){var input=$("#chat-group-new__members__right__field__js").val()〜.fail(fucntion(){alert("通信エラー")});
};までです。
まず、varを使用し変数を宣言します。varはletとは異なり、値の再代入や再宣言ができます。
変数inputに.val()を使用して(ここに記述された値を取得します)、id="chat-group-new__members__right__field__js"を代入(つまり、検索をかけた時にその検索した内容の値を取得できます)。
↓ここのフォームに入力した値を取得
$.ajax({})
これはこれを記述することで画面を切り替えずに一部の情報をサーバーに送信して、情報を受け取ることができます。
type: リクエストタイプ(HTTP動詞)を決めます。GETかPOSTを選べますが、検索結果をただ表示したいだけなのでGETにしました。
url:送信先を指定します。
users GET /users(.:format) users#index
usersコントローラーのindexアクションへ送信したいのでurlである(/users)を記述します。
data:送信先へ送るデータをキー/値のペアで設定します。
keywordをキーとしてinputを値として送ります(つまり先ほどの変数inputで入力して取得した値)。
このデータはusersコントローラーのindexアクションへ渡されます。
dataType:サーバーから返ってくるデータの型を指定できます。
.done(処理内容)){
ここにデータの送受信が成功したときの処理を書きます。
.empty()を使用し、id="chat-group-new__member__search"の中を空にします(< id="chat-group-new__member__search">~</div>内)。
これにより、追加を押したら表示が消えます。
↓
▼チャット参加メンバー▼の上のaaa 追加が消えます。
if文を使用してusers.lengthは検索をかけた時にユーザーが何件ヒットするかによって分岐しています。
ユーザーが0件ヒットでなければ該当があったら)、forEachメソッドを使用してヒットしたユーザーを繰り返し処理をします。
その繰り返し処理された内容を、関数(addUser(user))に値を引き渡します。
input.length(検索フォームに入力された値)が0ならば(入力を消した場合)、イベントを中断します。
そうでなければ(ヒット件数0件)の場合は関数notUserを実行します。
↓
.fail(処理内容))
ここにはデータの送受信を失敗したときの処理を記述します。
alert()メソッドを使用し、通信エラーとアラートを表示します。
$(document).on(処理内容)
このdocumentはhtml要素へ簡単にアクセスすることができます。
https://qiita.com/k152744/items/6453923550d5e4166557
console.logを使い、documentを見てみると...
↓
https://gyazo.com/509e77874ce85173d89da109739f4ae4
今扱っているチャット新規作成ページのhtml要素を取得できてます。
そして、検索してヒットして「〇〇 追加」と表示され、この「追加」をclickしたらイベントが発火します。
変数をletで宣言します。
ここに記述してあるthisの中身↓
https://gyazo.com/b054fbfa854490c12f7e8d1c482c9429
これは追加をクリックした時のものです。
.attr()を使用し、このthisの中からdata-user-idとdata-user-nameを取得します。
そして取得した値を変数userName、userIdへ代入します。
https://techacademy.jp/magazine/26775(←.attr()について)
このthisは↓
です。
.parent()は一つ上の階層の親要素を取得することができます。
つまり↓
div class="chat-group-new__member__search__usersが親要素となります。
ここの要素から取得しています。
.remove()は$(〇〇).remove();の〇〇の要素を削除することができます。
よって、
↑を削除することができます。
.empty()と.remove()の違いは、emptyでは指定した要素の子要素のみが削除されます。
removeでは指定した要素の子要素まで削除されることになります。
つまりthisで取得しているものを削除したいのでremoveを使用します。
https://www.sejuku.net/blog/36261
そして変数に代入した値を引数を各関数へ渡します。
documentでhtml要素を取得し、「〇〇 削除」の削除をクリックした時にイベントを発火させます。
ここのthisは↓
https://gyazo.com/b776042932f00721eecce79ce8b30997
これを.parent()で一つ上の階層の親要素から取得します。
つまり↓
<div class="chat-grop-new__add__right__user">~</div>までを取得します。
.remove()で要素を削除します。つまりthis↓
を削除します。
app/views/layouts/application.html.erb
https://gyazo.com/12fa3e76860b6a93791fa9ebe6f79585
チャット新規作成ページへ遷移した際にイベント発生しないのを防ぐためにbodyにdata-turbolinks="false" としておきます。
これでturbolinksが悪さをするのを防ぎます。
完成
https://gyazo.com/7688b4702266b4c0dbc763d75aecdd6c
インクリメンタルサーチと非同期通信ができました。
以上です。
Ruby on Rails: チャットグループ機能(アイコン表示)の実装(CarrierWave使用)...chapter15
今日はusersテーブルとchat_groupsテーブルにアイコンを保存できるように各user_iconカラムとchat_group_iconカラムを追加したいと思います。
そして↓のようにユーザーページにアイコンを編集できるようにして、チャットグループでもアイコンを選べるようにして表示できるようにしていきたいと思います。
イメージ図:
やりたいこと
①DB設計(README)にアイコンを追加する
②カラム追加
③CarrierWaveの導入
④コントローラーの編集(chat_groups_controller.rb)
⑤ビューの編集(chat_groups/new.html.erb, edit.html.erb)
⑥コントローラーの編集(users_controller.rb)
⑦ルーティングの編集
⑧パスの変更
⑨ユーザーページの編集及び編集ページを作成
⑩ユーザーページのアイコンを表示
①①チャットグループへアイコンを表示
①②各アイコンを整える
①DB設計(README)にアイコンを追加する
user_icon、chat_group_iconをstring型で追加します。
②カラム追加
各テーブルにアイコンを保存できるようにカラムを追加していきます。
最初はusersテーブルに追加していきます。
$rails g migration AddUser_iconToUsers user_icon:string
↓
invoke active_record
create db/migrate/20200702130354_add_user_icon_to_users.rb
↓
↓
$rails db:migrate
https://gyazo.com/c86ff3c62fd5a9eaf928fc88c1e2adef
chat_groupsテーブルにも追加していきます。
$rails g migration AddChat_group_iconToChat_groups chat_group_icon:string
↓
invoke active_record
create db/migrate/20200702131112_add_chat_group_icon_to_chat_groups.rb
↓
↓
$rails db:migrate
https://gyazo.com/09cb4fa9cf93f2b7ac75ebe0479af2f7
③CarrierWaveの導入
Gemfile
↓
$bundle install
↓
$rails g uploader image
↓
create app/uploaders/image_uploader.rb
このファイルで保存方法を設定できる。
↓
app/models/user.rb
mount_uploader :user_icon, ImageUploaderを追加。
app/models/chat_groups.rb
mount_uploader :chat_group_icon, ImageUploaderを追加。
✍️ mount_uploader :(カラム名), (アップローダークラス)
modelに記述することにより画像をアップロードした際にImageUploaderクラスの設定を利用できるようになります。
アップロードされた画像はpublic/uploads下へ保存されます。
↓
$rails s(再起動)
これで準備完了です。
参照:https://qiita.com/nekotanku/items/5da43600f35eada64eac
参照:https://qiita.com/ttaka66/items/264dcb85e41f9135685c
参照:https://pikawaka.com/rails/carrierwave
④コントローラーの編集(chat_groups_controller.rb)
app/controllers/chat_groups_controller.rb
https://gyazo.com/400d0245070037c7d38f6c7042832705
newメソッド
@chat_group_new.users << current_user
・current_user
ログインしているユーザー
・<<
尖っている方に開いている方の情報を付け加える(@chat_group_new.usersへ情報を付け加えている)
・@chat_group_new
chat_groupsテーブルのインスタンス
・.users
.usersで@chat_group_newに所属しているusersテーブルのレコードを配列[]で取得できる。
これでログインしているユーザー(current_user)を@chat_group_new(chat_groupsテーブルのインスタンス).users)に加える(<<)ことができます。
https://gyazo.com/f2f6f12730330cdf45386fde83acf523
ストロングパラメーターに:chat_group_iconを追加。
⑤ビューの編集(chat_groups/new.html.erb,edit.html.erb)
先にチャットグループ新規作成でアイコンを保存できるようにしたいと思います。
https://gyazo.com/ff25eafa6a342e6903bb9e50284f79c4
file_fieldはファイル入力ボタンを作成します。
:chat_group_icon(カラム名)を指定して、今回はchat_group_iconカラムに保存できるようにしています。
↓
http://localhost:3000/chat_groups/new
↓
新規作成してみます。
↓
次は編集ページでも画像をアップロードできるようにします。
https://gyazo.com/d5b0c16d4af5786991e79889786e4ca4
↓
http://localhost:3000/chat_groups/8/edit
ファイルを選択できるようになったので編集してみます。
↓
↓
編集前:
編集後:
icon_kari.png → tsuki.png へ変更できているので成功です!
⑥コントローラーの編集(users_controller.rb)
https://gyazo.com/3624de02731658ae98959c22c20132d6
ユーザーページから『アカウント設定』リンクをはり、ニックネームとアイコンを編集できるようにしたいので、user_pageでログインしているユーザーのidを取得し、@user_infoに代入。
editメソッドでもユーザーのidを取得しインスタンス変数へ代入することで編集ページへ情報を渡せるようにしました。
そしてupdateメソッドでも同様にユーザー情報をedit_userへ代入し、ストロングパラメーター を通して、updateメソッドで編集した内容を保存できるようにしました。
ストロングパラメーターで許可したのは編集できるようにしたいnicknameとuser_iconをpermitに設定しました。
⑦ルーティングの編集
https://gyazo.com/4b069503182affd9b264961a63918bac
resourcesを使って一括に設定。
その中でも今回使うのはeditアクションとupdateアクションなのでonly: [:edit, :update]とすることでこの2つのルーティングを設定しました。
また、user_pageはonlyで設定できないので、追加したいアクションを記述できるcollectionを使ってブロック内に記述しました。
しかし、これだとprefixのpathが変わってしまうのでサインアップ、ログイン後のpathを変更しないといけません。
なので、変更していきます。
⑧パスの変更
app/controllers/application_controller.rb
app/views/chat_groups/index.html.erb
⑨ユーザーページの編集及び編集ページを作成
先にユーザーページの編集をします。
https://gyazo.com/701067588f35ea73d4ad0753ed18f460
編集ページへのパスは/users/:id/editなのでlink_toメソッドを使用し、パスは"/users/#{@user_info.id}/edit"としました。
↓
↓
app/views/users/edit.html.erbを作成。
↓
https://gyazo.com/80380b0b39a93fa5687765ac2b5b285a
updateへのpathは/users/:idなのでurl: "/users/#{@edit_user.id}"を設定。
また、form_withのデフォルトHTTP動詞はpostなのでmethod: :patchを設定。
↓
ユーザーページから『アカウント設定』をクリック。
↓
編集してみます。
↓
↓
https://gyazo.com/662fd586bfac5a928a26f2079b1c0bba
大丈夫そう。
⑩ユーザーページのアイコンを表示
ここで注意しなければならないのはアイコンを登録してないユーザーはデフォルトアイコン画像↓
でなければならないことです。
なので最初にデバッグをしながら処理内容を決めていきたいと思います。
user_page.html.erb
分かりやすいように一番下でdebugをしてみます。
@user_infoにはユーザー情報が含まれています。
その中でuser_iconのfileはどうかをアイコン登録者と未登録者で比較してみます。
アイコン登録者:
未登録者:
登録してあるユーザーではfile:のところにどこにアイコン画像が保存されているか書かれています。
しかし、未登録者では...となっていて何も書いていません(nil)。
これを使ってif文で分岐させて処理させれば良さそうです。
↓
app/controllers/users_controller.rb
fileがある、つまり登録者は@user_iconへアイコンのurl(どこへ保存されているか)の情報を代入。
未登録者では@user_iconへデフォルトアイコン画像を代入しています。
次にビューを編集していきます。
↓
app/views/users/user_page.html.erb
image_tagに@user_iconとコードすることでアイコンのurlを代入します。
↓
http://localhost:3000/users/users/user_page
登録あり:
登録なし:
ユーザーページでのユーザーアイコンの表示は問題なさそうです。
①①チャットグループへアイコンを表示
現在のチャットグループは↓のような表示になっています。
なのでチャットグループへアイコンを表示してみたいと思います。
イメージ図:
まだチャットグループへのメンバー登録機能は実装していないので、アイコンはグループ作成者のみアイコンが表示されるようにしたいと思います。
ここでも注意することがあります。先ほどと同様にアイコンを登録していない人はデフォルトアイコンを表示させるようにしなければなりません。
また、チャットグループのアイコンも同じで登録していない場合はデフォルトの画像を表示しなければなりません。
今回使用するチャットグループデフォルトアイコンは↓のものにしようと思います。
それではやっていきたいと思います。
最初にチャットグループのアイコンが表示できるようにします。
app/controllers/chat_groups_controller.rb
ユーザーのアイコン表示と同じようにアイコンのファイルが何もない(nil)場合= 画像がある場合は@chat_group_iconにアイコンのurlを代入。
なければ@chat_group_iconにデフォルトアイコン画像を代入。
↓
app/views/chat_groups/show.html.erb
↓
登録あり:
登録なし:
アイコンを表示することに成功しました。
次にユーザーアイコンを表示させます。
app/controllres/chat_groups_controller.rb
@chat_group
ここではchat_groupsテーブルから表示する情報をidから引っ張り出してきます。
これでレコード(横{行})が取得できました。
@chat_members
ここではwhereメソッドを使用し、chat_group_idカラムの中で@chat_group.id(表示したいページのid)を中間テーブル(chat_groupとuser)から探してきます。
これで同じチャットに参加しているメンバーのidも取得できるようになりました。
@chat_members_info
先ほどの@chat_membersを使用し、参加メンバーの情報を取得します。
@chat_members.idではなく@chat_members.idsで複数のユーザーの情報を取得できます。
app/views/chat_groups/show.html.erb
https://gyazo.com/92804441949ae74f811590bf8065ab64
ユーザーページのアイコンやチャットグループのアイコンのように1つだけの画像を表示ならばコントローラーへコードしインスタンス変数を持ってくれば大丈夫なのですが、2つ以上のアイコンを表示する場合、つまり情報を一つ一つ取り出す際はhtmlの方で分岐をコードしなければいけないみたいです。
each do |〇〇|で一つずつユーザー情報を取り出す処理をしています。
今は作成者のみですが、今後メンバー追加するときにこれでメンバーのアイコンを表示することができます。
コードできたので表示されるかやってみます。
↓
登録あり:
登録なし:
できてます。
最後にアイコンを丸くし整えます。
①②各アイコンを整える
チャットグループでのアイコン(グループアイコン、ユーザーアイコン)を丸く表示したいので、今回は@mixinと@includeを使用してスタイル(今回は大きさと丸くするスタイル)を使い回したいと思います。
@mixinと@includeはセットで使用します。
これを使うと共通のスタイルが多い場合とかにコードが楽になります。
また、コードも見やすくなり一石二鳥です✌️
参照:https://stand-4u.com/css/sass/mixin.html
app/assets/stylesheets/chat_groupsフォルダを作成。
app/assets/stylesheets/mixinフォルダを作成。
↓
app/assets/stylesheets/chat_groups/show.scssファイルを作成。
app/assets/stylesheets/mixin/_icon_setting.scssファイルを作成。
↓
app/assets/stylesheets/application.scss
これで使えるscssが使用できるようになりました。
↓
app/assets/stylesheets/chat_groups/show.scss
https://gyazo.com/5755c84bb5086403be8e4b4ad88b5297
大きさと丸みの設定してみました。
これでよかったら @mixinと@includeを使用して書いていきたいと思います。
↓
app/assets/stylesheets/mixin/_icon_setting.scss
@mixin (任意の付けたい引数名){
(処理内容)
}
app/assets/stylesheets/chat_groups/show.scss
https://gyazo.com/834e69f01ecf19a5e914d3966edc624a
@inculde (@mixinで付けた引数名);
これで@mixinから@inculdeにデータが引き継がれ使えるようになります。
では、ビューを確認してみます。
↓
完成しました。
次回はチャットメンバーを追加できるように実装していきたいと思います。
その際に、インクリメンタルサーチ(入力した文字に該当する候補を出してくれる機能)と非同期通信(ページを遷移せずに一部だけを更新できる機能)を使用し追加できるようにします。
この2つスクールで学習してましたが、とりあえず完成させて提出したって感じで理解できないままやってましたね^^;
そのせいで実装に苦労しました。
このブログでもう一度実装し、記憶を定着させられるようにしたいと思います。
インクリメンタルサーチ:https://gyazo.com/f0f6a5b5ed8ebf2d6477373d0da548f9
非同期通信:https://gyazo.com/6644ad0a2b4eca5249326856dbb20ce7
以上です。
Ruby on Rails: チャットグループの詳細ページ、編集、削除機能の実装...chapter14
今日やりたいこと
・チャットグループの詳細ページの作成
・チャットグループ編集機能の実装
・チャットグループ削除機能の実装
この3つをやろうと思います。
最初にチャットグループの詳細ページを作成します。
①チャットグループの詳細ページの作成
1.コントローラーの編集
app/controllers/chat_groups_controller.rb
ChatGroupモデルを使用し、params[:id]を使用しchat_groupsテーブルからidを探してチャットグループ情報を取得。
@を変数につけてインスタンス変数にして@chat_groupに取得したチャットグループ情報を代入。
2.詳細ページの作成
app/views/chat_groups/show.html.erbを作成。
↓
https://gyazo.com/08889858d742773eb9528663d6bd8e20
チャットグループの説明
もしchat_groupsテーブルのchat_group_description(グループの説明)カラムが空欄なら。。。
説明を表示してください。
それ以外なら(説明文がない場合)。。。
『説明文はありません。』と表示してください。
if文終了してください。
3.詳細ページの確認
/説明文がない場合
//説明文がある場合
②チャットグループ編集機能の実装
現在一覧ページは↑のようになっています。
メンバーカウント数の横に編集リンクを作りたいと思います。
そして、編集フォームに保存されているグループ名と説明をフォームに表示させるようにしたいと思います。
1.編集リンクを作成
一覧ページに編集リンクをつけていきます。
$rails routes
edit_chat_group GET /chat_groups/:id/edit(.:format) chat_groups#edit
↓
app/views/index.html.erb
↓
http://localhost:3000/chat_groups
2.コントローラーの編集
app/controllers/chat_groups_controller.rb
editアクション
先ほどの詳細ページ(showメソッド)と同じ処理。
今回はインスタンス変数を@edit_chat_groupとしました。
updateアクション
チャットグループを探し、変数update_chat_groupへ情報を代入。
編集して送られてきた情報をストロングパラメーター(chat_group_paramsメソッド内)にかけている情報だけを通す。
そしてupdateメソッドを使用し、内容を更新してDBへ保存。
3.編集ページの作成
app/views/chat_groups/edit.html.erbを作成
↓
https://gyazo.com/07ac61e8b45b19496f41dcaabefefa48
form_withのデフォルトHTTP動詞は'post'なので、methodでpatchを指定。
url
PATCH /chat_groups/:id(.:format) chat_groups#update
$rails routesで確認。
url: '/chat_groups/#{@edit_chat_group.id}'
これでupdateアクションへ行けそうです。
↓
チャットグループ一覧ページから[編集]をクリック。
↓
これを編集してみます。
↓
これで編集するボタンをクリックし、一覧ページへ戻ってみると。。。
↓
詳細ページ:
大丈夫そうです。
③チャットグループ削除機能の実装
最後にチャットグループを削除できるようにしていきます。
1.コントローラーを編集
チャットグループを探して、destroyメソッドで削除を指示。
↓
2.削除リンクを貼る
編集の横に削除パスを貼ります。
$rails routes
DELETE /chat_groups/:id(.:format) chat_groups#destroy
パス先は"/chat_group/#{list.id}"。
↓
3.ビューの編集
app/views/chat_groups/index.html.erb
link_toのデフォルトHTTP動詞は'get'なので methodを使用して'delete'と指定。
↓
4.確認
http://localhost:3000/chat_groups
削除できるかやってみます。
グループ3を削除してみます。
↓
[削除]をクリック
↓
http://localhost:3000/chat_groups
削除できてます。
今回は過去の復習でした。
昔だったら時間をかけて作っていたと思いますが、今回はすらすら作成できました😄
以上です。
Ruby on Rails: チャットグループ一覧ページの作成...chapter13-4
今回やりたいこと
・グループの新規作成機能の実装
・チャットグループ一覧からチャット新規作成ページへ遷移できるようにする
・チャットグループ一覧へ所属するグループ名と参加人数を表示。
①chat_groups_controller.rbの編集
$rails routes
https://gyazo.com/4065f05257221c26bb9a47d043aac3ee
↓
app/controllers/chat_groups_controller.rb
ChatGroupモデルを使用し、newでインスタンスを生成。
②新規作成ページを作成(仮) + チャットグループ一覧ページから新規作成ページへリンク
app/views/chat_groups/new.html.erbを作成
↓
↓
app/views/chat_groups/index.html.erb
↓
リロード🔁
http://localhost:3000/chat_groups
グループ新規作成クリック
↓
これで新規作成ページに遷移できるようになりました。
③新規作成ページを作成
app/views/chat_groups/new.html.erb
form_withを使用しcreateアクションのパスへ飛ばしたいので、パスはchat_groups_path。
さらにmodelを使用し、どこのテーブルに情報を送りたいのかを示します。
↓
リロード🔁
フォームは出来ました。
次にこのフォームで入力した情報を保存できるようにcreateアクションを作成し、保存できるようにします。
④コントローラーにcreateアクションを追加
createアクションの処理内容
ChatGroup.newでインスタンス生成をして、変数chat_group_newに代入。
その際に、いらない情報も保存されないようにストロングパラメーターを設定。
もしchat_group_newがセーブできたら、簡易メッセージで'チャットグループを作成しました'と表示し、リダイレクト(遷移先)にindexアクションを設定。
情報をセーブできない場合はアラートとして'チャットグループ作成に失敗しました'と表示。
⑤情報を保存できるか確認
$rails s
↓
新規作成してみると。。。
↓
新規作成ボタンをクリックした瞬間にindexページへ遷移する。
アドレスバーにチャットグループを作成しましたと簡易メッセージが表示される。
Sequel Proでもみてみる。
保存できている。
しかしチャットグループを作成した場合、”チャットグループリスト表示”されないとおかしいです。
理由としてはこのチャットグループ一覧ページで設定したif @chat_group_joining == にあります。
これはindexアクションでの処理内容ですが、@chat_group_joining = ChatGroupToUser.where(user_id: current_user.id)でChatGroupUserToUserモデルを使用し、chat_group_usersテーブル(中間テーブル)からuser_idカラムからログインしているユーザーを探してきてと命令しています。
なのでchat_group_usersテーブルにログインしているユーザーがないと”チャットグループリスト表示”は表示されません。
chat_group_usersテーブルをみてみます。
やはり、保存されていません。
なので保存されるように設定していきたいと思います。
⑥保存できるように修正
app/views/chat_groups/new.html.erb
text_field_tag 'chat_group[user_ids][], "#{current_user.id}", type: hidden'
text_field_tagはフォームを作成し、送りたい情報を送れるようにするメソッドです。
構成は以下のようになっています。
text_field_tag (テキストボックス名, 初期文字列, {オプション1, オプション2,,,})
テキストボックス名
テキストフィールドのidとnameに割り当てられる。
フォームからの値を取得するキーになる。
初期文字列
テキストフィールドのデフォルト値。
指定された文字列が入力された状態で表示される。
オプション
今回はtype: hiddenを設定。
これで情報は送れるが、フォームはなくなります。
type: hidden設定なし
type: hidden設定あり
これで送られている情報は↓のようになっている。
<input type="hidden" name="chat_group[user_ids][]" id="chat_group_user_ids_" value="5" />
↓
これで一旦グループを作成してみる。
↓
保存はできているが、「参加していません」になっている。
理由は
https://gyazo.com/1c55a541b0afaa610748aa26bcad6f59
ストロングパラメーターにuser_idsを受け取れるようにしていない。
とりあえず、ストロングパラメーターにuser_idsを設定してみる。
↓
:user_idsとしたのは
Parameters: {"authenticity_token"=>"daUxVjXs0ZCF6gsdjnb1ZLDTOUJExuUKKpOtOEPB973R+V5o54jNR8P0Rkb+rfkXqhO24w+2Vt1WmvzmBY9Jvw==", "chat_group"=>{"user_ids"=>["5"], "chat_group_name"=>"グループ2", "chat_group_description"=>"グループ2"}, "commit"=>"新規作成"}
Unpermitted parameter: :user_ids
user_idsを受け取るときに配列となっている。なので、配列で受け取れるようにを設定。
これでリロードし、作成してみる。
↓
リロード🔁
新規作成してみる。
↓
遷移できてない。
https://gyazo.com/afeee14471c243f133441bd768bd7f42
今度はエラー内容をみてみると、
ArgumentError (wrong number of arguments (given 0, expected 1..2)):
ArgumentError(引数の数が間違っている(0の場合、1..2が必要)):
と書いてある。
また、
app/controllers/chat_groups_controller.rb:26:in `'
app/controllers/chat_groups_controller.rb:26:in `chat_group_params'
app/controllers/chat_groups_controller.rb:15:in `create'
これはこの書いてあるところが怪しいと言っています。
↓
:user_ids→user_ids:へ変更。
↓
リロード🔁
新規作成してみる。
↓
https://gyazo.com/800f1e7c3dd376377105ef8c94d4aaa6
ActiveModel::UnknownAttributeError (unknown attribute 'user_ids' for ChatGroup.):
このエラーを解決していきます。
↓
$rails c
pry> show-models
ChatGroupの
has_many :chat_group (through :chat_group_to_users)
ここが間違ってました。ここは中間テーブルのchat_group_to_usersを経由してusersテーブルと紐付けると示す場所なのにchat_groupテーブル(しかもhas_manyなのに複数形にもしてない...)に紐づけてしまっています。
なので、has_many :users (through :chat_group_to_users)と変更。
これでトライしてみます。
↓
$rails s
↓
↓
チャットグループリスト表示になりました!
Sequel Proも開いて確認。
中間テーブルにも保存されています!
それでは次はチャットグループ一覧ページに所属するチャットグループと所属人数が
⑦グループ一覧ページに所属するチャットグループ名と所属人数を表示する。
https://gyazo.com/bac3874bccce832c6de2605713c982bf
<% else %>~<% end %>を変更。
@chat_group_list.each do |list| ~ end
ここで、chat_groupsテーブルに入っている情報(今回はグループ1〜3まで)を繰り返し、一つ一つ取り出してます。
if list.user_ids.include?(current_user.id) ~ end
そのDBに保存されているuser_id達の中にcurrent_user(ログインしている)ユーザーは含まれているかを聞いてます。
link_to "/chat_groups/#{list.id}" do ~ end
まだグループの詳細ページは作成していませんが、詳細ページへ飛べるように式展開を使用しリンクを貼りました。
list.chat_group_name
ここで、所属しているチャットグループ名を表示。
list.user_ids.count
所属しているuser_id達をカウント(countメソッド)してくださいと命令。
これでリロードしてみてみます。
↓
リロード🔁
できてます。
さらにグループ4も登録してみてみます。
問題なさそうです。
今回はチャットグループを作成し、一覧ページに表示できるようにしました。
エラーがたくさん出て苦労しましたが、エラー構文の勉強になるので良かったかも(?)
次回はチャットグループ詳細ページ、編集、削除を実装していきたいと思います。
以上です。