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
以上です。