hiyoko-programingの日記

プログラミングを勉強したてのひよっ子。   エンジニア目指して勉強中。

ChatSpace MVCの作成

 ルーティングの設定を行う

仮のルーティングを設定する。ルートパスへのアクセスがあったら、messages_controllerのindexアクションが呼び出されるようにする。

ルーティングを以下のように設定。

config/routes.rb
1
2
3
Rails.application.routes.draw do
  root "messages#index"
end

 コントローラーとビューを作成

ターミナル
1
$ rails g controller messages index

コントローラー作成時に、コントローラー名に続けてアクション名を指定している。それによって以下の変更がされていることを確認。

・messagesコントローラーにindexアクションが作られている
・viewsのmessagesフォルダにindex.html.hamlファイルが作られている

※なお、この時点ではグループの作成機能やメッセージの投稿機能は未実装です。全て仮置きでビューを作成していきます。そのため、モデルやテーブルを作成する必要はない。

 DBを作成

アプリが正しく動くか確認しますが、あらかじめDBが作られていないとエラーになってしまう。

ターミナル
1
$ rails db:create

 ここまでの結果をチェック

ここまでの処理で正しく動作するか確認する。

サーバーを起動して、以下の画面が正しく表示されるか確認。

https://tech-master.s3.amazonaws.com/uploads/curriculums//910245aa11118186221f4dd322a88092.png

ビューはまだコーディングしていないので、このようにデフォルトの表示がされれば大丈夫。

Sassを使う準備をする

ビューのコーディングを行う前の準備をする。

 application.cssのファイル名を変更する

ファイルの拡張子が異なるとscssを使えないため、以下の操作を行う。

①app/assets/stylesheets/application.cssの中身を全て消す
②application.cssの拡張子を変更して「application.scss」にする

 これから追加する全てのスタイルシートはapplication.scssから@importを使って読み込む。

 reset.scssの設定をする

ブラウザによってデフォルトで設定されているスタイルをリセットするため、以下の操作を行う。

①app/assets/styleseetsディレクトリに_reset.scssファイルを作成

②application.scssに以下の記述を行い、reset.scssを読み込むようにする

application.scss
1
 @import "reset";

③ChatSpaceでは、YUI 3のリセットファイルを使用。以下のYUI3を先程作成した_reset.scssにコピーする。

1  2  3  4  5  6  7  8  9
10 11
12 13
14 15
16 17 18 19
20 21
22 23
24 25
26 27 28
29 30
31 32
33 34
35 36
37 38 39
40 41
42 43
44 45
46 47 48
49 50
51 52
53 54
55 56
57 58
59 60
61 62
63 64
65 66
67 68
69 70
71 72
73 74
75 76
77 78
79 80
81 82 83
84 85
86 87
88 89
90 91
92 93
94 95
96 97
98 99
00
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*!
 * YUI 3.5.0 - reset.css (http://developer.yahoo.com/yui/3/cssreset/)
 * http://cssreset.com
 * Copyright 2012 Yahoo! Inc. All rights reserved.
 * http://yuilibrary.com/license/
 */
/*
    TODO will need to remove settings on HTML since we can't namespace it.
    TODO with the prefix, should I group by selector or property for weight savings?
*/
html{
    color:#000;
    background:#FFF;
}
/*
    TODO remove settings on BODY since we can't namespace it.
*/
/*
    TODO test putting a class on HEAD.
        - Fails on FF.
*/
body,
div,
dl,
dt,
dd,
ul,
ol,
li,
h1,
h2,
h3,
h4,
h5,
h6,
pre,
code,
form,
fieldset,
legend,
input,
textarea,
p,
blockquote,
th,
td {
    margin:0;
    padding:0;
}
table {
    border-collapse:collapse;
    border-spacing:0;
}
fieldset,
img {
    border:0;
}
/*
    TODO think about hanlding inheritence differently, maybe letting IE6 fail a bit...
*/
address,
caption,
cite,
code,
dfn,
em,
strong,
th,
var {
    font-style:normal;
    font-weight:normal;
}

ol,
ul {
    list-style:none;
}

caption,
th {
    text-align:left;
}
h1,
h2,
h3,
h4,
h5,
h6 {
    font-size:100%;
    font-weight:normal;
}
q:before,
q:after {
    content:'';
}
abbr,
acronym {
    border:0;
    font-variant:normal;
}
/* to preserve line-height and selector appearance */
sup {
    vertical-align:text-top;
}
sub {
    vertical-align:text-bottom;
}
input,
textarea,
select {
    font-family:inherit;
    font-size:inherit;
    font-weight:inherit;
}
/*to enable resizing for IE*/
input,
textarea,
select {
    *font-size:100%;
}
/*because legend doesn't inherit in IE */
legend {
    color:#000;
}
/* YUI CSS Detection Stamp */
#yui3-css-stamp.cssreset { display: none; }

 messages.scssの設定を行う

以下の操作を行って、追加するscssの設定が読み込まれるようにする。

①app/assets/stylesheetsに、「modules」ディレクトリを作成。
②①のディレクトリ内に、「_messages.scss」という名称でファイルを作成。
③application.scssファイルを以下のように編集。

app/assets/stylesheets/application.scss
1
2
@import "reset";
@import "modules/messages";

FontAwesomeを導入

FontAwesomeはウェブフォントの一種で、文字を扱うのと同じようにアイコンを表示させることができる。FontAwesome用のGemがあるのでインストールを行なっていく。

 FontAwesomeを導入する

① gemをインストール

Gemfile
1
 gem 'font-awesome-sass'

Gemfileに追記したら、「bundle install」を行った後、サーバーを再起動。

② 続いて、application.scssに以下の記述を追加。

application.scss
1
2
3
4
@import "reset";
@import "modules/messages";
@import "font-awesome-sprockets";
@import "font-awesome";

これでFontAwesomeを使うための準備は整った。

 paddingなどでサイズが変わらないように設定

CSSの仕様で、paddingなどの設定を行った場合、その要素全体のサイズが大きくなってしまう。
それを避けるために以下の記述を追加する。

messeges.scss
1
2
3
* {
  box-sizing: border-box;
}

この設定をすることで、paddingやborderの設定を行っても、要素の大きさがwidthやheightで指定したサイズのまま変わらなくなる。

また、上記で設定している「*」というセレクタは、全ての要素に適用させるという意味。

サイドバーとチャット画面のビューファイルを作成する

ウェブサイトのコーディングでは、絶対的な正解の手順はない。
画面左のサイドバーと、画面右のチャット画面でファイルを分けて実装していく。

 hamlファイルを作成

①app/views/sharedフォルダを作成
②①のフォルダに以下の名前でファイルを作成

_side_bar.html.haml
_main_chat.html.haml

 ビューファイルを読み込む

以下のコードを参考に、app/views/messages/index.html.hamlからサイドバーとチャット画面のビューが読み込まれるように設定する。

messages/index.html.haml
1
2
3
.wrapper
  = render "shared/side_bar"
  = render "shared/main_chat"

部分テンプレートの読み込みなので、ファイル名先頭の「_」や拡張子は必要ないことに注意する。

 動作の確認を行う

部分テンプレートが、正しく読み込まれることを確認。
「_side_bar.html.haml」に<サイドバー>と、「_main_chat.html.haml」に<チャット画面>と仮で文字を記述する。

記述できたらアプリを表示してみる。

https://tech-master.s3.amazonaws.com/uploads/curriculums//623386ff0f88b52e2bcf43e5a3e4f461.png

ここでは、今追加した文字が表示されることだけ確認できれば大丈夫。

ビューのコーディングを行う

HTMLのクラス名を決める

BEMのルールに従ってクラスの命名を行う。
コーディングしながら名前をつけるのは効率が良くないため、最初にクラス名の設計を行う。

 クラス名を紙に書き出す

ChatSpaceの大雑把なデザインを紙に書いて、その全ての要素についてクラス名を決める。

https://tech-master.s3.amazonaws.com/uploads/curriculums//e8db167c3a64eb30f91ba78c19aa5459.png

コーディングに使うメモなので、自分がわかる程度の書き方で大丈夫。

またクラス名は、適切な名称を考えて命名する。書き出したら、BEMのルール通りの名前になっているかチェックする。

これからコーディングを行っていく際、メモを見ながら進めると効率よく作業することができる。

 

全体的なレイアウトを行う

 ビューを2つに分割する

最初に、サイドバーとチャット画面を作っていくために左右で2つに分割する。
先ほど決めたクラス名で、HTMLとscssのコーディングを行う。

https://tech-master.s3.amazonaws.com/uploads/curriculums//4c08350b9620761745d81a89120b57c9.png

上図のレイアウトになるようコーディングを行う。
記述できたらブラウザでビューを開いて、それぞれの「要素の幅」と「背景色」が指示通りになっているか確認。

 以下の見た目になるようビューのコーディングを行う

次に左右それぞれを、必要な数のdivで分割する。

https://tech-master.s3.amazonaws.com/uploads/curriculums//46e4164e2461f38d821ca013873b807d.png

コードを追加するごとに、正しくデザインできているか確認ながら進めていく。

また、「上下の高さの残り」の部分のコーディングは、以下のキーワードで調べてみる。

検索キーワード

これからのコーティングの流れを確認

全体的なレイアウトができたので、ここからはパーツごとに実装を進めていく。

https://tech-master.s3.amazonaws.com/uploads/curriculums//78845f7854a0bd6b5eb4e0920e081622.png

上図の①〜⑤の順で進める。

①ユーザー名とアイコンを表示させる

サイドバー上部に、ユーザー名とアイコンが表示されるようコーディングする。

https://tech-master.s3.amazonaws.com/uploads/curriculums//551c5384a163f6dca9636c870caacb73.png

HTMLでのレイアウトは最初は難しいため、少しずつステップを区切って進めていく。
この部分では以下の配置を行う必要がある。

  • ①ユーザー名やアイコンが、ボックス全体の上下中央に並ぶようにする
  • ②ユーザー名は左側に、アイコンは右側に分かるように配置する
  • ③2つのアイコンが左右に並ぶように配置する

 上下中央に並べる方法

サイドバーの上部に、ユーザー名とアイコンを表示するための準備を行う。

https://tech-master.s3.amazonaws.com/uploads/curriculums//b45040dc13b3434dbecab399e4ae095a.png

最初から要素を配置するのではなく、どうすればボックスの上下中央に要素を配置できるのか確認から行う。

上図のように、外側のブロック①の上下中央にブロック②が来るようにコーディングする。一時的にブロック②に色をつけるとレイアウトが見やすくなる。

配置のための方法はいくつかあるが、以下のキーワードで検索してみるのがおすすめ。

検索キーワード

「display flex align-items」

 左右に離してレイアウトする方法

続いて、今作成したブロックの中に、名前とアイコンが左右に分かれて表示されるよう配置していく。

https://tech-master.s3.amazonaws.com/uploads/curriculums//6ae141d8d84a51d93e5b208c9d1a25e9.png

最初に、2つ子要素を作成し、左右に並ぶようレイアウトを行う。

それぞれの要素は以下のようにコーディング。

ユーザー名(左側)

仮置きしたユーザー名が表示されるようにする。親要素の一番左側、上下中央に表示されるようにする。

アイコン(右側)

親要素の右端に表示されるようにする。次のステップで、内側に2つのアイコンを配置する。

検索のヒント

以下の2つをヒントに実装の方法を調べる。
「display flex justify-content」

「line-height 中央」

 アイコンを左右に並べる①

これからアイコンを左右に並べるが、少し複雑なので2段階に分けて考える。
まず下記の状態になるようにする。

https://tech-master.s3.amazonaws.com/uploads/curriculums//7be5d9e7ed750a0bb4718faae5eaad71.png

  • FontAwesomeのアイコンが表示されている
  • アイコンが左右に並んでいる
  • アイコンがリンクになっていてクリックすることができる

この状態になるようコーディングしましょう。なお、リンク先はまだありませんので、URLとして「#」を指定しておきましょう。

 

検索ワード

  • 「link_to アイコン」

 アイコンを左右に並べる②

左右に並べたアイコンの調整を行う。

https://tech-master.s3.amazonaws.com/uploads/curriculums//41daea8841de03d7eb4d83c3d44b2530.png

  • アイコンの色の変更
  • アイコンの下線を消す
  • アイコンを右端に配置
  • アイコン同士の間隔を5pxあける

以上の設定を行う。

なお、アイコンの位置を調整するためにはアイコンに対してクラスを設定する必要がある。font-awesome公式ドキュメントのページで、「class」を検索する(ページ内でコマンドキー + F)と設定の仕方の説明を読むことができる。

 

Hamlの書き方を確認

Hamlの書き方について、代表的な書き方だけおさえておく。
また、Hamlは厳格にインデント構造を揃えないとうまく反映されないので、注意して書く必要がある。

タグの書き方例

HTMLの書き方例
1
2
3
4
<form>
  <input type="submit">
  </input>
</form>
Hamlの書き方例
1
2
%form
  %input{type: "submit"}

クラスの書き方例

HTMLの書き方例
1
2
3
4
5
6
7
8
<div class="contents">
</div>

<div class="main content">
</div>

<form class="content">
</form>
Hamlの書き方例
1
2
3
4
5
.contents

.main.content

%form.content

Rubyタグの書き方例

HTMLの書き方例
1
2
3
4
5
6
7
<% messages.each do |message| %>
  <%= @message.content %>
<% end %>

<%= link_to messages_path, class:"group" do %>
  <%= @message.name %>
<% end %>
Hamlの書き方例
1
2
3
4
5
- messages.each do |message|
  = message.content

= link_to messages_path, class:"group" do
  = @message.name


aタグの装飾

link_toにちゃんとクラス名が書かれているか。aタグに対してちゃんとSCSSをあてているかを確認する。

検索ワード

  • css テキスト 右端」
  • haml クラス 設定」

 正しい色の設定を行う

ここまできたら設定作業はほとんど完了。
最後に、仮で指定していた背景色を正しい色に変更。

https://tech-master.s3.amazonaws.com/uploads/curriculums//9d81d105ed4d26d8f200c9f0c3f0e8b0.png

このようになれば、このブロックは完成。

このように、HTMLやCSSのコーディングを行うときは、 小さなブロックに分けて少しずつコーディングしていくことがポイント。

どう分割するのが良いか考えながら進めていく。

②グループ一覧を表示させる

次に、サイドバー下部にグループ一覧が表示されるようコーディングを行う。

 グループ一覧のコーディングを行う

上図の赤枠部分のように、グループ名とそのグループでの最新メッセージが表示されるようにコーディングする。表示データは仮置きで構わない。

https://tech-master.s3.amazonaws.com/uploads/curriculums//bf7ac78aa564e93808633974e5a3e135.png

上図の赤い枠がグループ1つ分のブロック。
完成したらHTMLをコピーして、複数のグループが表示されている見た目にする。

どのように表示させれば良いかわからない場合は、見本のChatSpaceを確認する。

f:id:hiyoko-programing:20200225124321p:plain

③グループ概要を表示させる

続いて、チャット部分を上から順にコーディングしていく。

 グループ概要のコーディングを行う

https://tech-master.s3.amazonaws.com/uploads/curriculums//e740ed5debf899f4219c4ccbcc5494f0.png

上図のデザインになるようコードを記述する。以下の点に留意する。

  • EditボタンはFlexBoxを使ってレイアウトする。
  • Editボタンにはリンクを設定する。ただし、リンク先のURLは「#」で構わない。

④メッセージ一覧を表示させる

チャット画面中央のメッセージ一覧の表示ができるようにする。

 メッセージ一覧のコーディングを行う

https://tech-master.s3.amazonaws.com/uploads/curriculums//73043588f97696b4661bcef5b858f946.png

グループ一覧と同様に、メッセージも複数表示されているような見た目にする。

複数のメッセージが表示されているように見えるよう、HTMLを複数回繰り返し記述する。

⑤投稿フォームを表示させる

最後に投稿部分のビューをコーディングする。

 投稿フォームのコーディングを行う

https://tech-master.s3.amazonaws.com/uploads/curriculums//215cd45eeacca7f7eb27c133ba2a52b0.png

この部分はいくつか実装が難しい場所がある。ポイントになる部分を調べながら、着実にコーディングしていく。

ブロック要素を重ねる方法

画像投稿用のアイコンが、テキスト入力フォームに重なって表示されるようにする。

https://tech-master.s3.amazonaws.com/uploads/curriculums//42182417d2b625b28c12e8d39e5742db.png

ところが、入力フォームは親要素になれないため実装には工夫が必要。

ChatSpaceの見本(http://chat-space-sample.herokuapp.com)

で確認する。検証ツールを使うと、テキスト入力エリアが実は2つに分割されていることがわかる。

 

上図のように、親要素の中に2つの子要素を横並びにすることで、1つのフォームのように見えるよう実装する。

また、ブロック要素の上にブロック要素を重ねるためにも少し工夫が必要になる。

https://tech-master.s3.amazonaws.com/uploads/curriculums//208dc96714d856ab825a3db4e1956cfa.png

親要素の上にアイコンを重ね、適切な位置に表示させるために、どのような設定が必要か調べて実装する

検索キーワード

css 重ねる position relative absolute」

ファイル投稿フォームを非表示にする方法

ChatSpaceでは、画像投稿用のフォームを使用している。通常このフォームを使うと、「ファイルを選択」というボタンが見えてしまう。

しかし、見えなくなるよう非表示にしてしまうとクリックすることができない。

これはラベルを使うことで解消できる。

https://tech-master.s3.amazonaws.com/uploads/curriculums//0e69564240a302871df9c09187324b25.png

ラベルの役割の1つは、ラベルがクリックされた時に、子要素もクリックされたことにしてくれること。

この仕組みを使うと、見えないはずのファイル選択ボタンをクリックしたかのように動作させることができる。

1
2
3
%label{class: "input-box__image"}
  = icon('fas', 'image')
  %input{type: "file"}