2022年2月28日月曜日

2月下旬の話題まとめ

2月21日

競馬

フェブラリーステークスが話題でした.ていうかこのメインレースだけがクラスタになるというのも珍しい.落馬事故から復帰してGI制覇という福永騎手もトレンドに上がっていました.

ニチアサ

そして日曜日なのでニチアサです.左上は仮面ライダー,右下はプリキュアでしょうか.ニチアサで括られて一つの大きな話題クラスタになっていました.

フィギュアスケート

フィギュアスケートも最後のエキシビションでおしまいです.北京オリンピックもこれでおしまいですね.

この他にも,カーリングのクラスタやリングフィットRTAなどの話題クラスタがありました.RTAってわかりますか.Real Time Attackの略で,ゲームをどれだけ速くクリアできるかを競う競技のことだそうです.

2月22日

乃木坂46時間TV

乃木坂46がデビュー10周年なんだそうです.それで「乃木坂46時間TV」などというものをやっているのだとか.YouTubeかしら?地上波ではないですよね.

西郷輝彦

俳優の西郷輝彦が前立腺癌でお亡くなりになりました.享年75歳,ご冥福をお祈り申し上げます.

猫適性テスト

shindanmakerです.2月22日がニャンニャンニャンで猫の日だそうで,猫適性テストだとか.今日は全体的に小粒な話題ばかりでした.オリンピックが終わって,ひと段落ついた,ということかしら.

2月23日

猫の日

さて,昨日とは打って変わって華々しいトピックマップになりました.右上のごちゃっとしたクラスタは,昨日が2022年2月22日ということで「猫の日」,それも22時22分22秒がどうしたとか,そんな話題ばかり.でも私は天邪鬼なので,「2022年2月22日22時22分22秒だワーイ」とかいうナイーヴなコメントには,「2022年の『0』は?『0』は?」とツッコミたくなってしまうわけで……損な性分です.

乃木坂46時間TV

一昨日から続く乃木坂46のイベントがまだ話題になっています.乃木坂46もTwitterで人気高いですね(そのくらいしかコメントできない).

ウクライナ

ウクライナ情勢がだいぶきな臭さを増してきました.ロシアが国境あたりの小さな国々に関して独立を認めた……って,ウクライナが認めるならまだしも,いくら旧ソビエトだったとはいえ,隣国からの独立を認めるって,相変わらずのジャイアンっぷりですなあ.

ウマ娘

今日はもう一つ、ウマ娘の大きなクラスタができていました.内容はよくわかりません.ウマ娘大好き芸人とあるのでアメトーーークでやったのかなと思いきやそれはガセだとか.

2月24日

乃木坂46時間TV

乃木坂の件がまだ続いています.なんで46時間TVなのに3日目?まあ,1日目がちょっとしかなければ46時間で3日をカバーできるか.フィナーレで相当盛り上がったということでしょうか.Twitterと乃木坂46は相性がよいのでしょうか.

テレ東音楽祭

そしてテレ東音楽祭です.これも大きなクラスタになっています.しかし……テレ東音楽祭とは,意外なキーワード.

ウクライナ情勢

米露外相会談が中止になり,ますますきな臭いムードになってきました.ウクライナ情勢は混迷を深めています.いやはや,どうなることでしょうか.

2月25日

ウクライナ

とうとうロシアが攻撃を始めちゃったようですね.極東のTwitterでも大きな話題クラスタができていました.ガソリン価格が急騰でレギュラーガソリン全国平均172円だとか.昨日,ハイオクのガソリン入れてきたけど会員価格で175円でした.安いほうなのかな.

ウマ娘

ウマ娘1周年だとか.いつも言っているけれど,あのゲームのコンセプトは全く共感できないので,コメントできないんだなあ.

岡田准一

ジャニーズのほうがまだ理解できる.岡田准一がジャニーズ初のブルーリボン賞を受賞して話題です.写真集も出すんだとか.ブルーリボン賞は,ザ・ファブルの主演男優賞だそうです.ザ・ファブル,漫画は面白かったので,映画も観てみようかなあ.そしてブルーリボン賞といえば鉄道の賞だとばかり思ってたよ.

2月26日

ロシア侵攻

とうとう戦争が始まってしまいました.しかし全時代的な印象だなあ.いまTVで,キエフを東京に例えて「自国で守らねばいかんねんでー」と解説している元防衛大臣,あざとい.あざとすぎる…… 日本のこととして考えるのは必要だが,おいおい,第三次世界大戦とか言い始めたぞぅ?

ELDEN RING

さて,こちらはのどかな話,テレビゲームです.エルデンリングというゲームが話題です.フロムゲーというキーワードを覚えました.FromSoftwareという会社が作っているゲームだそうで,全般的に難易度が高いんだとか.

青葉つむぎ

こちらもゲームがらみですが,アンスタ(あんさんぶるスターズ!)というゲームの派生文化でライブコンサートかなんかがあったようです.皆さんいろいろ考えますなあ(ビジネス目線).

2月27日

競馬

ロシア・ウクライナ情勢がいろいろと報じられてやばいことになっているなか,やはり週末なので競馬の話題クラスタが出現しています.中山と阪神ですね.ミンナノユメミノルなんていう素敵な名前の馬が走っていたようです.

一番くじ

一番くじの話題です.話題クラスタの上半分がBT21,下半分が鬼滅の刃関連のようです.BT21って何?と調べたら,BTSとLINEキャラクターのコラボなんですか.へー.勉強になりました.

ロシア

そしてロシア・ウクライナ情勢です.さすがに今回はロシアの分が悪いような印象ですが……国際社会はどのような判断を下してどんな結末を迎えるのでしょうか.

2月28日

ロシア情勢

ロシア・ウクライナ戦争が毎日大きな話題となっています.今日の話題は金融制裁が加えられたという点で,これはロシア経済にとって大きな打撃となりそうです.でもかわいそうなのはロシア国民ですよね.だいたいからして権力者が権力の座に長く留まると,ろくな結果にならない.ロシアだけじゃなくて,中国もやばい.日本はどうでしょう?

競馬(中山,阪神)

日曜日なので競馬です.中山競馬場では中山記念,阪神は11R(メインレース?)のみの馬名群で話題クラスタができあがっていました.他に話題が多かったせいか,いつもより控えめですね.

FGO

FGO生放送でメガネイベントがどうとか.よくわかりません(識者の解説求む).

プリキュア

プリキュアです.ニチアサですね.ニチアサのクラスタはもう一つ中規模なものができていました.

ポケモン新作

ポケモンの新作が発表されたそうです.

ホロライブメンバーソート

私の推しトップ5だそうです.ときどきこういうの出てきますよね

2022年2月27日日曜日

シンポジウム,ハイブリッド開催の経験から

(この内容は「ハイブリッド会議の最適解(続・ハイブリッド開催の経験から)」でアップデートされています.そちらをご参照ください)

2022年2月26日,中央大学iTLにて「にこP実践報告シンポジウム」が開催された.COVID-19の感染状況が芳しくないため,対面(オンサイト)とオンラインの併用での実施であった.参加者は40名ほどで,そのうち会場に来場したオンサイト参加者は1/4の10名程度であった.

ハウリング対策(オンサイトが主のケース)

オンサイトとオンラインの併用はいろいろと気を遣うことが多い.とくに問題となるのが教室で集まってオンライン会議システムに皆がログインすると,ハウリングが生じやすいという点である.

オンサイトが主で,オンラインが従である場合はほぼ問題はない.発表者だけに配信用のPCを用意,あるいは,発表用と配信用のPCを限定的に用意して,プロジェクタには配信用のオンライン会議画面を投影すればよい.基本的に発表用PCのマイクだけONにしておき,スピーカーとその他のPCのマイクは全てOFF(ミュート)にしておけば,ハウリングは生じない.

なお,この方法のよいところは,HDMIケーブルを抜き差ししてとか,外部ディスプレイ設定がうまくできないとか,そのテのトラブルが生じない点である.さらに,今回使った教室ではPCの画面を無線で飛ばしてプロジェクタで投影する機能が備えられているのだが,投影するPCを配信用PCに限定しておくことで,「全てのPCでその機能の恩恵を受けられる」という利点も享受できる.ネットワークに繋がりさえすれば,参加者が持ち込んだPCの資料を簡単にプロジェクタへ投影できるというメリットがある(マイクはミュートとしておく).

ハウリング対策(オンラインが主のケース)

問題は,オンラインが主のケースである.ネットワークの向こう側から発信される資料を共有する点は問題ない.配信用PCの画面をプロジェクタに投影しておけばよいという点は先に述べたケースと同様である.

ここで問題となるのがオンラインから配信された音声をどうするか.工夫しないとすぐにハウリングが発生してしまう.簡単な解決策は,全員デバイスを用意して全員がイヤホンで聴くという方法である.これであればハウリングは発生しない.音声だけ聴こえればよいので,スマートフォンでオンライン会議に参加してもらうという点が妥当なところだろう.

もう一つの方法は,配信用PCの音声だけ,会場のマイクで拾って教室に流すという手である.この方法だとハウリングを起こさずに教室内に音声を流すことができる.ただし,教室側で誰かが話しているときにスピーカーがONになっていると発話のタイムラグが生じて話者が話しにくくなるので,オンライン側が発生しているときだけスピーカーをONにするなどの工夫が必要となり,オンラインと教室でインタラクティブな議論が生じると,操作者はけっこう忙しい.オンライン側からはチャットで質問をもらうなどの工夫が必要となるだろう.

2022年2月21日月曜日

講義動画はしっかり観てほしい

早稲田大学で講義動画を同時視聴でごまかした学生が100人も不可となったという事件?がちょっとした話題になっている.オンデマンド型のオンライン講義をどう視聴するかということに関しては,2倍速で見るのはけしからんとか,対面授業の出席と同じだとか,様々な意見がある.私自身は,最終的に知識が身に付けばどのような視聴方法でも構わないのではないかと考えているものの,同時視聴ではどっちつかずで知識なんて身に付かんだろう.聖徳太子じゃあるまいし.

ただし,私自身は,これがベストと考える方法で動画を提供しているので,2倍速ではさすがに速すぎて情報が欠落するだろうと危惧するし,短縮視聴するにしてもせいぜい1.5倍程度までにしてほしいと願っている.

ある学生の事例

ところで,学生の視聴スタイルを見ていて,気付いたことがある.プログラミングに関する講義で,全学全キャンパスの学生を対象に開講している科目のため,オンデマンド型のオンライン講義として提供されている.

あるとき,ある学生が「どうにもうまくいかないんですけど」と何度も質問してきた.最初はLMSのメッセージで何度もやりとりしていたものの,埒が開かず,幸いにして同じ学部の学生だったために,特別に教室で指導することとなった.

トラブルの原因は……

「うまくいかない状況を再現してみ」と指示したところ,その学生は,動画を飛ばし飛ばし見ながら作業していることに気付いた.その動画では,端末のスクリーンショット動画を盛り込んで,デモンストレーションしながら解説している.その部分だけを切り取って,作業していたのである.

トラブルの原因は,端末のデモ以外で,するべき作業があり,その作業をしていないことだった.資料にはその旨もしっかり説明しており,動画でも,きちんと念を押して解説していた.しかし,当該学生の視聴方法ではスキップされてしまうのであった.

勝手な視聴スタイルに問題あり

つまるところ,きちんと動画を視聴していればなんら問題ない話(他の学生はそのとおりきちんとできている)だったのだが,勝手な視聴方法によって,うまくいかなくなっていたというだけのオチだったわけだ.

講義内容をしっかり理解できていない学生ほど,講義動画をきちんと観てほしいところである.

2022年2月20日日曜日

2月中旬の話題まとめ

2月11日

クワッドアクセル

結局のところゆづは4回転ジャンプ失敗しちゃいました.でも公式記録としては4回転半が認定?よくわからない結末になりましたが,まあ,お疲れ様でした.羽生結弦もそろそろ引退していいんじゃないかな.それにしても,クワドラプルアクセルじゃないかということがとても気になります.

(追記:TVでの解説によると,4.0回転以上,4.25回転以内だったということで,技としては「認定」だけれども「成功」ではない,という状態だったとのこと.難しいなあ)

サイゼリヤ

なぜか突発的にバズるサイゼリヤ1000円ガチャ.また現れました.最初は面白いこと考えよったなーと好印象でしたが,こう何回も出てくると,もう飽きたよっていう感じなんだけど,なんで,こう,定期的に出現するんでしょうか.不思議です.

乃木坂46ANN

ここのところ毎週金曜日になると現れていた乃木坂46オールナイトニッポンの話題クラスタ,今週も現れました.誰ぞがパーソナリティを引退するとかしないとか,たしかそんな話でしたっけ?

2月12日

平野歩夢

スノーボードのハーフパイプ,平野歩夢が金メダルをとりました.その話題で中心に大きなクラスタができています.技の名前も気になります.私はアナウンサーがフォーティフォーティを連呼していたのが気になります.何度聞いても4040にしか聞こえない.ちゃんと発音してほしい.

Mステ

右上にできているクラスタはミュージックステーションですね.やはりTV番組とTwitterは切っても切れない関係にあるようです.金曜日の夜にMステのクラスタができるのも珍しいことではありません.

サイゼリヤ

そして一昨日に引き続きサイゼリヤ1000円ガチャです.昨日の朝早くというか深夜のトレンドなので,一昨日の夜から続いて話題になっていたということですね.

2月13日

競馬

昨日は土曜日でしたので,お約束の競馬クラスタができております.東京と阪神です.東京はクイーンカップというレースがメインだったようですね.その他,小倉も小さなクラスタができていますが,こちらはさほど盛り上がらなかった様子.

Twitter不具合

Twitterのシステムに障害があったようです.もっとも,障害発生中はアクセスできないはずだから,障害が終わってから怨嗟の声で盛り上がったということかな?幸にして私自身はツイ廃というわけではないので,気づきませんでした.

藤井聡太

藤井聡太が史上4人目,最年少での五冠達成ということだそうです.いま,彼の持っているタイトルって何と何と何だっけ?全部で8つあるんですよね.プロレスみたいだな(違うか).

カーリング

さて,タイトルは盛り上がってるクラスタから3つを選んでいるわけですが,昨日は大きく盛り上がっていた話題が他にもいくつかあったので,順に紹介します.一つ目はカーリング.なんだかスーパープレイが生じたようですね.見てて面白かったでしょう.

ウクライナ

そしてこちらはきな臭い話.ウクライナ情勢がますます悪くなっているようです.邦人に退避勧告が出たようです.オリンピックの閉会式を待たずに武力侵攻が始まるとか始まらないとか?平和の祭典,オリンピックの間は戦争しないとかなんとかいう建前は,どうなっているのでしょう?

2月14日

競馬

日曜日なので,競馬の大きなクラスタができています.共同通信杯,京都記念,こぶし賞,バレンタインステークスというレースが行われたようです.バレンタインデーですからね.共同通信杯は東京,京都記念は阪神のメインレースです.バレンタインステークスは東京のメインレースの一つ前,こぶし賞は阪神8Rとのこと.

プリキュア

中央にある緑のクラスタは,プリキュア関連のようです.プリキュアも根強い人気があります.ニチアサの一角を担っています.

鬼滅最終回

鬼滅の刃,日曜深夜に放映されているアニメも今シリーズは最終回だそうです.いつもは深夜の放映を受けてその後に話題クラスタが発生するため,月曜日の恒例行事という感じでしたが,今日は最終回ということで,早々と話題が盛り上がっていたのでしょう.

その他に,左上にサッカーのクラブW杯に関連すると思しき話題クラスタができていました.社会的イベント関連の話題が,競馬やニチアサの影に隠れてしまうのは,いかがなものかな?と思わぬでもありません.

2月15日

バレンタインデー

昨日はバレンタインデーでした.というわけで,たいがいな大きさの話題クラスタ,ゴチャッとした塊が下のほうにできています.みなさん,楽しいバレンタインデーを過ごしましたか?ハッピーバレンタイン!

鬼滅の刃最終回

そして昨日は月曜日だったので,前日の日曜深夜の放映を受けて,鬼滅の刃クラスタができています.しかも最終回ということでいつもよりも大きめのそれが,右上にドカンと現れています.が,バレンタインデーの超絶ボンバーに霞んでしまいました.

ローソンとサンリオコラボ

もう他はたいした話題はありません.いくつか,中規模程度のクラスタがありますが,どれも霞んでしまっています.ローソンとサンリオがコラボしてなんだかの商品を出したらしいです(解説する気なし)

2月16日

サマソニ

3年ぶりの開催となるサマーソニック2022,25組の出演アーティストを大公開!だそうで,その話題がクラスタになっていました.こうやってもうなし崩しにいろいろなことが元に戻っていくんだろうな.人間ってテキトーで,そこが面白い.

ウマ娘コラボ

ファミマがオンラインゲームのウマ娘とコラボして,「(馬名)の(商品名)」という企画商品をいろいろと販売している件が話題になっていました.しかもそこそこ美味しいらしい.しかし,なんで幼い女の子が競馬場をかけっこせにゃならんのだ……あのゲームにはどうも共感できない.

木下富美子

お騒がせ元都議です.無免許運転を繰り返して事故まで起こしてちゃいけませんな.しかもその後の対応もまずかった.執行猶予付きの判決だそうで,甘い!の大合唱ですが,もう社会的にはだいぶ酷い目に遭っているんだから,許したれよ?

2月17日

フィギュアスケート

オリンピックの女子フィギュアスケートが話題です.まあ,ワリコワのドーピング疑惑とか,いろいろと胡散臭い話も含めて,話題がとっちらかっている印象がありますな.関連してロシアのウクライナ侵攻みたいな話題まで繋がっちゃっているし.

DBD貞子

さてこちらはよくわからなかったので調べてみたところ,Dead By Daylight(DBD)というゲームの新シリーズに,貞子が登場するということで盛り上がっていたようです.DBDとリングのコラボ企画ということだそうです.まあ,なんでもコラボするよねー,という話.

あつこお姉さん

小野あつこお姉さんって誰?と思えば,「おかあさんと一緒」のお姉さんを演じていた人だそうです.4月で卒業だとか.大きいお友達関連が盛り上がっているのでしょうか.Eテレもときどき話題になりますね.

2月18日

カーリング

昨日はオリンピック関連の大きな話題クラスタが2個できていました.中央にある水色の話題クラスタは,左半分がカーリング,右半分がスピードスケートの高木選手です.「有終の美」というキーワードで繋がっていました.

フィギュア女子

オリンピック関連の話題クラスタ,もう一つは女子フィギュアスケートです.ロシア勢強し.ドーピング疑惑がいまだに拭われていませんが.そしてロシアに関連した話題としてウクライナ侵攻の話題がまたしても紛れ込んでしまっています.致し方なしということでしょうか.

SnowMan

テレビ番組の話題です.テレ東でSnowManの冠番組「Snow Manが豪邸でシェアハウスしてみた」という番組が始まるというので話題です.ジャニーズ+TVという組み合わせは鉄板です.

2月19日

フィギュア女子

昨日と同じく女子フィギュアスケートとカーリングの話題が盛り上がっています.フィギュアスケートは坂本花織選手が銅メダルという話題に,例によってロシア問題.ウクライナの話題までが混じってしまっています.

カーリング

カーリングは破れたものの競っていた韓国も敗れて決勝にギリギリ進むことができたってところまではTVで見て知っていましたがその後どうなったのかな.

あなまど

そしてshindanmakerです.「あなたの引越し先の間取り」だそうです.オリンピックの話題に紛れてサクッとこういう話題で盛り上がるのがTwitterの面白いところ.似たような話題クラスタがもう一つできていて,そちらはBISHセンター試験だそうです.

2月20日

オリンピック

フィギュアスケート(ペア)とカーリングの話が「日本勝利」というキーワードで接続され,一緒になって大きなクラスタとなっています.カーリングは決勝進出したんですね.カーリングも,女子のクラスタと男子のクラスタは別にできているようですが,それも「決勝の相手」というキーワードで繋がっています.

競馬

競馬です.昨日は土曜日でした.東京と阪神という名前が見えます.京都牝馬ステークスというキーワードもあるので,京都でも開催されていたんですかね.

Snow Man岩本照

ひーくん主演映画という話題です.ジャニーズ強し!Snow Manの岩本照が映画単独初主演とのこと.「モエカレはオレンジ色」という漫画の実写化だそうです.ヒロインはめるる.めるるだのひーくんだの,赤ん坊か?

2022年2月19日土曜日

【今日の招太郎】オフトゥン大好き

明け方,布団のなかに入れろと主張が激しいので入れてやるとこのザマ.

図々しいにも程があるぞ?

それにしても気持ちよさそうに寝てござるな.



2022年2月15日火曜日

ActionCableを用いたチャットアプリの作成

事前準備

今回,下記の手順で動作を検証したバージョンは,Ruby,Railsともに次のとおりである.

$ ruby --version

ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [arm64-darwin20]

$ bin/rails --version

Rails 7.0.2.2

$ 

Railsの雛形を次の手順で用意する.

$ mkdir chatroom

$ cd chatroom

$ rbenv local 3.0.2

$ bundle init

Writing new Gemfile to /private/tmp/chatroom/Gemfile

$ vi Gemfile

Gemfileの # gem 'rails' の行,「# 」を削除してコメントアウトを外す.

$ bundle config set path vendor/bundle

$ bundle install

Fetching gem metadata from https://rubygems.org/...........

Resolving dependencies...

Fetching rake 13.0.6

Installing rake 13.0.6

Fetching minitest 5.15.0

(中略)

Fetching rails 7.0.2.2

Installing rails 7.0.2.2

Bundle complete! 1 Gemfile dependency, 47 gems now installed.

Bundled gems are installed into `./vendor/bundle`

$ bundle exec rails new . -f

       exist  

      create  README.md

      create  Rakefile

   identical  .ruby-version

      create  config.ru

      create  .gitignore

      create  .gitattributes

       force  Gemfile

         run  git init from "."

(中略)

Import Stimulus controllers

      append  app/javascript/application.js

Pin Stimulus

      append  config/importmap.rb

$ 

以上で準備はOK.

チャットルームへの第1歩

roomsコントローラを作る.とりあえず,今回は一つのルームで一つのページしか表示しないSingle Page Application (SPA)なので,showメソッドだけ作ればよい.

$ bin/rails g controller rooms show

      create  app/controllers/rooms_controller.rb

       route  get 'rooms/show'

      invoke  erb

      create    app/views/rooms

      create    app/views/rooms/show.html.erb

      invoke  test_unit

      create    test/controllers/rooms_controller_test.rb

      invoke  helper

      create    app/helpers/rooms_helper.rb

      invoke    test_unit

$ 

config/routes.rb を次のように修正する.localhost:3000/ にアクセスすると,Roomsのshowメソッドにルーティングされるように記述する.

Rails.application.routes.draw do

  root to: 'rooms#show'

end

データベースを作る.

$ bin/rails db:create

Created database 'db/development.sqlite3'

Created database 'db/test.sqlite3'

$ 

今回はテストなので,デフォルトのSQLite3をそのまま使う.

確認

サーバを起動する.

$ bin/rails server

=> Booting Puma

=> Rails 7.0.2.2 application starting in development 

=> Run `bin/rails server --help` for more startup options

Puma starting in single mode...

* Puma version: 5.6.2 (ruby 3.0.2-p107) ("Birdie's Version")

*  Min threads: 5

*  Max threads: 5

*  Environment: development

*          PID: 32482

* Listening on http://127.0.0.1:3000

* Listening on http://[::1]:3000

Use Ctrl-C to stop

ブラウザを立ち上げて,localhost:3000 にアクセスする.

この画面が出ればOK.

メッセージのモデルを作成

メッセージのモデルを作る.文字列(text)型のbodyカラムを一つだけ持つ,たいへんシンプルなモデルである.

$ bin/rails g model message body:text

      invoke  active_record

      create    db/migrate/20220215115613_create_messages.rb

      create    app/models/message.rb

      invoke    test_unit

      create      test/models/message_test.rb

      create      test/fixtures/messages.yml

$ bin/rails db:migrate

== 20220215115613 CreateMessages: migrating ===================================

-- create_table(:messages)

   -> 0.0006s

== 20220215115613 CreateMessages: migrated (0.0007s) ==========================


$ 

モデルを作成したあとは,マイグレーションを忘れずに.

チャットルームのビューとコントローラを作成

次はルームのビューとコントローラを作成する.既に先のコマンドで雛形が作成されている.

app/controllers/rooms_controllers.rb を次のように修正する.Mssageモデルから,全てを取ってきて(Message.all())@messageに入れている.

class RoomsController < ApplicationController

  def show

    @messages = Message.all()

  end

end

部分レンダリングを使うので,app/views/messages ディレクトリを作成する.部分レンダリングとは,ページの一部分だけをレンダリングするものである.今回は多くのメッセージを順番に表示するので,そのメッセージの表示部分だけを部分テンプレートとして用意しておく.

$ mkdir app/views/messages

そのディレクトリに app/views/messages/_message.html.erb を次の内容で作成する.これが部分テンプレートとなる.メッセージのボディ(内容)だけを表示する.

<div class="message">

  <p><%= message.body %></p>

</div>

Roomsのビューも作る.app/views/rooms/show.html.erb を次の内容で作成する.

<h1>Chatroom</h1>

<div id ='messages'>

  <%= render @messages %>

</div>

render @messages というコマンドで,@messages に含まれるメッセージを,部分レンダリングとして用意したものとしてまとめてレンダリングしてくれる.

テストデータの投入

Railsコンソールから,テストデータを投入する.

$ bin/rails c

Loading development environment (Rails 7.0.2.2)

irb(main):001:0> Message.create! body: '庭には二羽鶏がいる'

   (0.7ms)  SELECT sqlite_version(*)

  TRANSACTION (0.0ms)  begin transaction                      

  Message Create (0.6ms)  INSERT INTO "messages" ("body", "created_at", "updated_at") VALUES (?, ?, ?)  [["body", "庭には二羽鶏がいる"], ["created_at", "2022-02-15 12:25:23.071306"], ["updated_at", "2022-02-15 12:25:23.071306"]]

  TRANSACTION (0.5ms)  commit transaction                     

=> 

#<Message:0x0000000123e157e8

 id: 1,

 body: "庭には二羽鶏がいる",

 created_at: Tue, 15 Feb 2022 12:25:23.071306000 UTC +00:00,

 updated_at: Tue, 15 Feb 2022 12:25:23.071306000 UTC +00:00>

irb(main):002:0> 

$ 

とりあえずは一つ用意しておけばよいだろう(複数,用意すれば,部分レンダリングがきちんと対応していることも確認できる).

確認

サーバを起動する.

$ bin/rails s

ブラウザを立ち上げて,localhost:3000 にアクセスする.

コンソールから入力したデータが表示されればOK.

フォームの作成

フォームを用意する.app/views/rooms/show.html.erb を次のように修正する.

<h1>Chatroom</h1>

<div id ='messages'>

  <%= render @messages %>

</div>

<form>

  <label>Leave your message:</label><br>

  <input type="text" data-behavior="room_speaker">

</form>

Railsのフォーム作成用ヘルパーメソッドも使えるが,今回は割愛.

確認

サーバを起動する.

$ bin/rails s

ブラウザを立ち上げて,localhost:3000 にアクセスする.

フォームが表示されればOK.

ルーム・チャネルの作成

Roomに対するチャネルを次のコマンドで作成する.

$ bin/rails g channel room speak

      invoke  test_unit

      create    test/channels/room_channel_test.rb

   identical  app/channels/application_cable/channel.rb

   identical  app/channels/application_cable/connection.rb

      create  app/channels/room_channel.rb

      create  app/javascript/channels/index.js

      create  app/javascript/channels/consumer.js

      append  app/javascript/application.js

      append  config/importmap.rb

      create  app/javascript/channels/room_channel.js

        gsub  app/javascript/channels/room_channel.js

      append  app/javascript/channels/index.js

$ 

app/channels/room_channel.rb が今回使用するチャネルの主要部分である.

サーバ側の処理

app/channels/room_channel.rb を次のように編集する.

class RoomChannel < ApplicationCable::Channel

  def subscribed

    stream_from 'room_channel'

  end


  def unsubscribed

    # Any cleanup needed when channel is unsubscribed

  end


  def speak(data)

    ActionCable.server.broadcast('room_channel',

                                 { message: data['message'] })

  end

end

subscribedメソッドで’room_channel' からデータを取得すること,speakメソッドで各クライアントにbroadcastすることを,それぞれ記述する.

クライアント側の処理

app/javascript/channels/room_channel.js を次のように編集する.

import consumer from "channels/consumer"


const appRoom = consumer.subscriptions.create("RoomChannel", {

  connected() {

    // Called when the subscription is ready for use on the server

  },

  disconnected() {

    // Called when the subscription has been terminated by the server

  },

  received(data) {

    // Called when there's incoming data on the websocket for this channel

    return alert(data['message']);

  },

  speak: function(message) {

    return this.perform('speak', {message: message});

  }

});


window.addEventListener('keypress', function(e) {

  if (e.keyCode === 13) {

    appRoom.speak(e.target.value);

    e.target.value = '';

    e.preventDefault();

  }

})

この処理で,フォームからサーバに送られたデータがブロードキャストされて,各クライアントのreceived()が受け取り,それぞれでアラートが表示されるようになる.

サーバを起動し,ブラウザのウィンドウを複数立ち上げて,どこか一つからメッセージを投げると,全てのウィンドウでアラートが出ることを確認せよ.

あとは,受け取ったクライアント側で,アラートを出すのではなく,Chatのメッセージを表示するように画面を書き換えれば,リアルタイムチャットアプリの完成である.

データベースに記録するように修正

app/channels/room_channel.rb のspeak(data) を修正.

class RoomChannel < ApplicationCable::Channel

  def subscribed

    stream_from 'room_channel'

  end


  def unsubscribed

    # Any cleanup needed when channel is unsubscribed

  end


  def speak(data)

    Message.create! body: data['message']

  end

end

データベースに記録するように変更した.チャネルのspeak処理を消してしまったので,データベースにデータをコミットした後に非同期で動作する処理を追加し,そこでspeak処理を行うように修正する.

speak(data) で Message.create! した直後に,そのまま broadcast() してもよいが,クライアント数が多くなったときにそれらへのブロードキャスト対応を別途切り分けて実施することでシステムを安定して動作させることを狙っている.

app/models/message.rb を次のように修正する.

class Message < ApplicationRecord

  after_create_commit { MessageBroadcastJob.perform_later self }

end

commitの後で(after_create_commit),次に作るジョブMessageBroadcastJob を実施する(perform_later)という記述である.

ジョブの作成

次の手順でジョブを作成する.

$ bin/rails g job MessageBroadcast

      invoke  test_unit

      create    test/jobs/message_broadcast_job_test.rb

      create  app/jobs/message_broadcast_job.rb

$ 

app/jobs/message_broadcast_job.rb を次のように修正する.

class MessageBroadcastJob < ApplicationJob

  queue_as :default


  def perform(message)

    ActionCable.server.broadcast('room_channel',

      { message: ApplicationController.renderer

                   .render(partial: 'messages/message',

                           locals: { message: message }) })

  end

end

ApplicationController.renderer.render() で,message がよしなにレンダリングされたものが,全てのクライアントにbroadcastされる.

クライアント側の修正

サーバから各クライアントに broadcast されたメッセージを,クライアント側のブラウザに表示されているHTMLに反映させるように,JavaScriptによるクライアント側の処理を修正する.

app/javascript/channels/room_channel.js を,次のように変更する.

変更するのは received(data) の部分.

import consumer from "channels/consumer"


const appRoom = consumer.subscriptions.create("RoomChannel", {

  connected() {

    // Called when the subscription is ready for use on the server

  },


  disconnected() {

    // Called when the subscription has been terminated by the server

  },


  received(data) {

    const messages = document.getElementById('messages');

    messages.insertAdjacentHTML('beforeend', data['message']);

  },


  speak: function(message) {

    return this.perform('speak', {message: message});

  }

});

window.addEventListener('keypress', function(e) {

  if (e.keyCode === 13) {

    appRoom.speak(e.target.value);

    e.target.value = '';

    e.preventDefault();

  }

})

以上で完成である.サーバを起動し,複数のブラウザを用意して,それぞれのブラウザからメッセージを入れて同期することを確認せよ.

完成

完成すると,こんな感じで動くよ.

本記事は「【Rails6.0】ActionCableを使用したライブチャットアプリを実装する手順を解説」というブログを参考にした(ただし記事のとおりやっても,Railsの最新版だとうまくいかなかったので,注意.若干の修正を加えている).そちらにも丁寧な解説が示されているので,参考にされたい.