TECH EXPERT 23日目 Ruby文法 補足
1.条件分岐処理 if以外
case文 #並列する条件が多数ある場合 ifより記述がシンプルに。
例
case 対象のオブジェクトや式 #この部分が条件の対象
when 値1
# 値1に一致する場合に実行する処理
when 値2
# 値2に一致する場合に実行する処理
when 値3
# 値3に一致する場合に実行する処理
else
# どれにも一致しない場合に実行する処理
end
2.繰り返し処理 each 以外
while (ワイル) 繰り返し構文 #指定した条件が真である間、処理を繰り返す。
while 条件式
# 条件が真である時に繰り返す処理
end
※この条件式は無限ループになる場合もある。 変化する変数 number+=1 を入れない場合など↓
if文などの条件分岐とbreakを使う。
例:
if number == 5
break
end
3.ブロックについて
ages.each do |age| これの do~end までが 「ブロック」
puts age |age| のage はブロック引数と呼ぶ
end
↓ do~end 以外に{} を使う書き方もある。
ages.each {|age| puts age}
自分でdef定義したメソッドでブロックを使う。
yield:メソッドに渡されたブロックを実行するための命令。
Rubyの文脈においては「取って代わられる」に近い。引数を守る門番
使い方
def greeting(&block) #ブロックの引数を明確に受けとるため引数に”&”をつける
puts "Hello"
block.call("Goodbye")
end
greeting do |text|
puts text
end
# ターミナル出力結果
# Hello
# Goodbye
4.Ruby クラスの理解 効率的なコードを書く
クラスの継承 親クラス→子クラス
継承のやり方
class PoliceCar < Car ←のように 新しいクラス < 元となるクラス と記述
end
継承されるもの 利点
※子クラスに新しくメソッドも追加できる。
メソッドの上書き可能
やり方→ 親クラスにあるメソッドを子クラスで定義する
メソッドの オーバーライドと呼ぶ。
クラス継承メリット
継承すれば、親クラスで定義されているメソッドを使えるようになる。
あるカテゴリーの共通要素を親クラスに定義して継承させれば、同じメソッドを何度も定義する必要がなくなり効率的である。
5.Rubyに最初から用意されてる機能
→ライブラリ
ライブラリの種類 3つ
標準ライブラリ インストール不要 明示的に記述が必要 例 Date
組み込みライブラリ インストール不要 例 String
外部ライブラリ(gemのこと) インストール必要 記述必要
使い方 (組み込みライブラリは読み込みいらず)
標準ライブラリ
「require ライブラリ名」
require "date"
puts Date.today #Dateクラスに使える todayメソッド の実行
# ターミナル出力結果
# 20xx-xx-xx(本日の日付が表示)
外部ライブラリ(gemのこと)
①使いたいgemをインストールする
ターミナル「gem install gemの名前」
②インストールしたgemをrequireで読み込む
「require ライブラリ名」 標準ライブラリと同じ
6.例外処理
例外処理の必要性
プログラムが正しくても環境、ユーザーの動作でエラーを引き起こしてしまうことは多々ある。→その結果や状態を例外(期待されるものと異なる状況)と呼ぶ。
これを予期して、例外が発生したときに行う例外処理を定義しておく。
※例外処理をしておくことで緊急事態を早期復旧させたり、カバーが可能。
1つ目「メインの処理に失敗したらそのときだけ別の処理を実行して、そのままメインの処理を続ける」
begin(ビギン):
beginは、例外となりそうな箇所を囲い処理を実行できる文法です。
どんな条件でも最低1回は処理を実行するため、例外処理を始めるときなどに使用します。
(例)
begin
# 例外が起きると想定される処理
end
例外になりそうな箇所を捉える必要がある?
rescue を使う #例外が発生しそうな部分をbeginから始まるブロックで囲み、ブロックの内部にrescueを記述して使用
rescue:発生した例外を捕捉し、例外が起こった際に呼び出される条件節です。
例外が起こったときに実施する処理。
raise(レイズ)
raiseは、例外を発生させることができる文法。
第一引数に発生させたい例外クラス、第二引数にエラーメッセージを記述して使用
「raise 発生させたい例外クラス, 'エラーメッセージ'」
※ログを残して原因を特定しやすくできる。効率よくプログラムする上では強スキル。
2つ目 「メインの処理に失敗したらそのときだけ別の処理を実行して、メインの処理すべてをなかったことにして中止する」
トランザクション #レコードの更新を行う複数の処理を一つにまとめて行う。
全ての処理の成功 or 全ての処理の失敗 の状態になる。
(例)
ActiveRecord::Base.transaction do
# 処理1
# 処理2
# ...
end
たとえば、ECサイトの購入処理では、「商品の料金支払い処理」「注文確定処理」を常に1つのまとまりとして考えられる。
トランザクションを利用することで、「料金の支払いに失敗したけど、商品は購入できた」「料金は支払ったけど、注文の確定に失敗し商品が届かなかった」といった事態を防ぐことが可能。
7.オブジェクト指向
アプリケーションを作成時、登場する役割ごとに分けて実装する方針のことを言います。RubyなどのWebアプリケーションに使用される言語の多くが、オブジェクト指向で実装する必要がある。
オブジェクト指向のメリット
・役割ごとにオブジェクトを分けることで、実装がしやすくなる
・役割ごとにオブジェクトを分けることで、あとからコードを改変するときも、他のオブジェクトに影響しなくなる(コードの改変がしやすくなる)
クラスを考える際は、「このアプリケーションにおいて、どのような処理が存在するのか」に着目すると良さそう。
単一責任の原則
「1つのクラスは1つの振る舞いしか持たない」原則
これを遵守しないと意図のわからないアプリケーションになる。
クラスごとにディレクトリを分割して require で読み込みを行う
require "./drink"
require "./vending_machine"
require "./user"
オブジェクト指向に正解はない。
アプリケーションにおける役割ごとにクラスがあり
そのクラスはその役割が持つ処理以上のことはできない。
TECH EXPERT 23日目 レスポンシブWEBデザイン
レスポンシブ対応のWebサイトを作る。
レスポンシブWebデザイン:画面幅によって見た目が変わるように、デザインを設計することをレスポンシブWebデザインと呼ぶ。
現在では、ユーザーがスマホやタブレットでサイトを閲覧することが主流なため、レスポンシブ対応は必須!!
レスポンシブWebデザイン対応の工程
①表示領域の設定をする
②画面サイズによってCSSを切り替えるための設定をする
③画面サイズごとに適用するCSSを記述する
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
事前準備
Noto Sans JP フォント Web現場ではよく使われるフォント
インターネットから読み込みが必要 Link要素でURL引っ張る→ Webフォント
GoogleFonts
Googleが提供するWebフォントのサービス 完全無料 様々なフォント
いろいろなフォント無料で使える。情報は宝です。
企画、ペルソナでクライアントにあった
フォントでサイトデザインすることを意識すべし。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
①表示領域の設定をする
スマホで表示するときに縮小して表示されないようにする。
viewportを設定する。 HTMLのheadタグ内に下記を記述
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
>
contentプロパティにwidth=device-width を指定することで
ブラウザの大きさを機器に合わせることができる。
※ initial-scaleは、画面の拡大率
②画面サイズによってCSSを切り替えるための設定をする
@media (max-width/min-width: 〇〇〇px) { }
という記述をメディアクエリという。
使用例#画面幅が500px以下の時にのみ、pタグのfont-sizeを10pxにしたい
@media (max-width: 500px) {
p {
font-size: 10px
}
}
※ max-widthに対してmin-widthも存在
Webサイトをレスポンシブ対応させるときには、この記述を使ってレイアウトや文字の大きさなどをデバイスの幅に合わせて調節する。
ブレークポイント:メディアクリエによって規定したスタイル適用の分岐点
上記の場合は 500pxがブレークポイント
ブレークポイントの値を何pxにするか、何箇所ブレークポイントを置くかは制作するWebサイトの要件による。
③画面サイズごとに適用するCSSを記述する
/* PC表示時 */
p {
font-size: 30px
}
/* タブレット表示時 */
@media (max-width: 1000px) {
p {
font-size: 25px
}
}
/* スマホ表示時 */
@media (max-width: 500px) {
p {
font-size: 20px
}
}
確認方法
指定したデザインになってるかは検証モード(サイト右クリック)
検証ツールのデバイスモード(右サイドバー上のスマホマーク)では、様々なデバイスのサイズでWebサイトの表示が確認できる。500px と501px で比較
TECH EXPERT 19日目 チャットアプリ開発 5. サーバーサイドの実装
今 コミットしながら思ったのですが GitHubに保存することで
過去に行ったアプリケーション作成手順を分解して見れる+流れもわかるので
類似品なら1から作れる。それ以上も出来そう。控えめに神か?
まだ管理、運用とかはピンとこないが自身がアプリケーション作るのに
これの存在は必須でしょうと感じた。
5. サーバーサイドの実装 (既存の部分なので新しい概念や気付き中心)
ルーム管理
before_action :authenticate_user! #ログイン済みユーザーとの条件分岐 メソ
コントローラーの先頭に、before_action :authenticate_user!
と記述するより、ログインしていないユーザーをサインアップの画面に促すことができます。
references 中間テーブル作成時使用
Railsで外部キーのカラムを追加する際に、用いる型
foreign_key: trueという制約を設けることで、他テーブルの情報を参照できる
コンソール操作 中間テーブルを通じてレコードを作成
「モデル名」+「_ids」 roomという親要素を保存するときに、
user_idsで所属させたいユーザーを配列で指定すると、その情報が中間テーブルに保存される仕組みになっている。
プルダウン作成 ビュー 以下2つの要素を使う
select要素
select要素:プルダウンのようなセレクトボックスを作成するための要素。select要素のname属性に任意の値を指定することで、paramsを通してその値をコントローラーへ渡すことが可能。
option要素:select要素の中でoption要素を記述することで、プルダウンの選択肢になる要素です。
ul li 要素のリスト化に近い
ログイン中以外のユーザーのレコード取得
User.all.where.not(id: current_user.id).each do |user| #現在ログインしてるユーザー以外のレコードの取得
モデル名.where("条件")と記述することで条件に一致したレコードを配列として取得できる。notは条件に一致したレコード以外。
コメント投稿機能
lメソッド
l(エル)メソッドは日付や時刻を表示するメソッド
日本時刻
ja:
time:
formats:
default: "%Y/%m/%d %H:%M:%S"
オプションにformatあり 書式切替
画像投稿機能
Active Storage
Active Storageとはファイルアップロードを簡単に実装できるGem
Messagesテーブルとimageカラムのアソシエーション
models/message.rbファイルを開いて、以下のように記述
has_one_attached :image
TECH EXPERT 19日目 チャットアプリ開発 4.フロント部分の実装
HTML、CSS ビューの部分
1.事前準備
GitHubでの管理を行う
ブランチの作成 「フロント実装」→コミット
フロント実装に必要なルーティング、コントローラー、ビューを作成する
仮のものでOK、作成後ちゃんと表示されるか一応確認しとく→コミット
リセットCSSが適用されるように設定する
app/views/layouts/application.html.erb
paddingなどで要素のサイズが変わらないように設定する
app/assets/stylesheets/application.cssファイルに設定。
box-sizing: border-box; を使う。
paddingやmarginを要素のサイズに含めることができるプロパティ。→コミット
フロント実装で使用するファイルを作成する
ビューファイルはサイドバーとメインチャットで分ける。
部分テンプレート使用↓
<%=render "side_bar" %> <%=render "main_chat" %>
※部分テンプレートの読み込みはファイル名頭の「_」、拡張子は必要ない→ コミット
詳細に関しては把握しきれないので
調べて実装などでも問題なさそう。記述自体は複雑でもないので。
2.ビューの実装
overflow: scroll; #はみ出した部分をスクロールされた時に考慮して
はみ出した部分があったらスクロールできるようになる
label要素
フォームの中でフォームの項目名とフォームの入力要素(画像選択フォーム、プルダウン、チェックボックスなど)を関連付けるための要素。
label要素の役割の1つは、label要素がクリックされた時に、子要素もクリックされたことにしてくれる。この仕組みを使うと、見えないはずのファイル選択ボタンをクリックしたかのように動作させることができます。
要素の横並びなど学んだ部分で作成可能、あとこまめにコミット。
逆に設計からどんなページの作成をするか具体的にイメージしてたから作りやすい
TECH EXPERT 19日目 チャットアプリ開発 3.土台作成
3. アプリケーションの雛形の作成
キーワード:GitHub アプリケーションの状態が管理
アプリ作成後にデータベース作成
GitHub使ってローカルリポジトリ→リモートリポジトリ作成
READMEにDB設計(①②を参考に)を記載(マークダウンで)
一番下に記載
テーブル名
カラム名
カラムの型
カラムのオプション(null false制約など)
アソシエーション
GitHubへのコミット、プッシュ を忘れずに行う。
README(リードミー):ソフトウェアの仕様、規格、インストール方法などを文書化したアプリケーションの説明書ファイル
マークダウン:マークダウンとは、文書を記述するための軽量マークアップ言語
HTMLに変換。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
テーブル名
カラム名
カラムの型
カラムのオプション(null false制約など)
アソシエーション
README.md に記述
# テーブル設計
## users テーブル
| Column | Type | Options |
| -------- | ------ | ----------- |
| name | string | null: false |
| email | string | null: false |
| password | string | null: false |
### Association
- has_many :room_users
- has_many :rooms, through: room_users
- has_many :messages
## rooms テーブル
| Column | Type | Options |
| ------ | ------ | ----------- |
| name | string | null: false |
### Association
- has_many :room_users
- has_many :users, through: room_users
- has_many :messages
## room_users テーブル
| Column | Type | Options |
| ------- | ------- | ------------------------------ |
| user_id | references | null: false, foreign_key: true |
| room_id | references | null: false, foreign_key: true |
### Association
- belongs_to :room
- belongs_to :user
## messages テーブル
| Column | Type | Options |
| ------- | ------- | ------------------------------ |
| content | string |
| user_id | references | null: false, foreign_key: true |
| room_id | references | null: false, foreign_key: true |
### Association
- belongs_to :room
- belongs_to :user
TECH EXPERT 18日目 Railsによる チャットアプリ開発 ①要件定義 ②データベース設計
ChatAppを開発 全体像の把握
以下の順で実装
1. 要件定義
2. DB設計
キーワード:中間テーブル
3. アプリケーションの雛形の作成
キーワード:GitHub アプリケーションの状態が管理
4. フロント画面の実装
チャット画面のみフロントの実装
5. サーバーサイドの実装
ユーザー管理機能 → チャットルーム管理機能 → メッセージ投稿機能の順に実装
6. サーバーサイドのRspecテスト
キーワード:Rspec
1.要件定義
機能
ユーザー管理機能(新規登録・ログイン・ログアウト機能)
チャットルーム管理機能(チャットルームの新規作成・削除機能)
メッセージ管理機能(テキスト投稿・画像投稿機能)
↓
usersテーブル { ユーザーの名前 ユーザーのEmail ユーザーのパスワード
roomsテーブル { チャットルーム名
messagesテーブル { テキストの内容 画像の情報 メッセージ投稿時刻
メッセージ投稿をしたチャットルーム メッセージ投稿をしたユーザー
ページ
サインイン/ログインページ
トップページ{リンク
チャット新規作成ページへ遷移できるリンクが存在する
ユーザー編集ページへ遷移できるリンクが存在する
指定のチャットルームへ遷移できるリンクが存在する
{表示
ログイン中のユーザーの名前が表示されている
ログイン中のユーザーがチャットルームを作成していれば、チャット名が表示される
ユーザー編集ページ
チャットルーム新規作成ページ{表示
プルダウンの中に、DBに保存されているユーザー名が表示されている
チャット名を記入するフォームが表示されている
チャットルームを作成するボタンが表示されている
チャット一覧,投稿ページ{リンク
チャット新規作成ページへ遷移できるリンクが存在する
ユーザー編集ページへ遷移できるリンクが存在する
指定のチャットルームへ遷移できるリンクが存在する
現在いるチャットルームを終了(チャットのデータを削除する)リンクが存在する
{表示
ログイン中のユーザーの名前が表示されている
ログイン中のユーザーがチャットルームを作成していれば、チャット名が表示される
メッセージや画像を投稿するフォームが表示されている
投稿したメッセージや画像が表示されている
投稿した日時が表示されている
投稿したユーザーが表示されている
2. DB設計
キーワード:中間テーブル
チャットルームとユーザーのエンティティ 関係
多対多 なのでアソシエーション組めず↓
解:中間テーブルを使う
= group -- group_user -- userのように2つのテーブルの間を繋ぐ。
group_userが持つのは 両方のテーブルのデータ(レコード横列でもつ)
中間テーブルは双方のidの組み合わせテーブルということ。
メソ has_many :モデル, through #〜を経由する
has_manyのthroughオプションは、モデルに多対多の関連を定義する。
ER図
TECH EXPERT 17日目 テストコード(コントローラー単体、複合)
※復習した時に更新してもうちょい見栄えよくします
コントローラーのテストコード書く方針
あるアクションにリクエストを送ったとき、想定通りのレスポンスが生成されるかどうかを確かめる。
exampleの整理が重要
Request Spec を使う
get
get 〇〇_pathのように、どこのパスにリクエストを送りたいかを記述
response
リクエストに対するレスポンス内容の確認
status
response.statusと実行することによって、そのレスポンスのステータスコードを出力 HTTPステータスコード 200〜299成功 400〜エラー
body
response.bodyと記述すると、ブラウザに表示されるHTMLの情報を抜き出せる
複合テストコード
System Specを記述するためには、CapybaraというGemが必要である。
visitで実際にアクセスしたいページに遷移できる。
visit 〇〇_path
pageは、visitで訪れた先のページの見える分だけの情報が格納されている。
have_contentはvisitで訪れたpageの中に取得したい文字列があるかどうかを判断できる。
expect(page).to have_content('X')と記述すると、visitで訪れたpageの中に、Xという文字列があるかどうかを判断
検証ツールでフォームの名前を取得して、
fill_inを用いて文字列を入力することができる。
fill_in 'フォームの名前', with: '入力する文字列'
find().clickはクリックしたい要素を指定することで、実際にクリックすることができる。
changeはモデルのレコードの数がいくつ変動するのかを確認することができる。
expect{ "何かしらの動作" }.to change { モデル名.count }.by(1)と記述することによって、モデルのレコードの数がいくつ変動するのかを確認
現在いるページのパスを示す。expect(current_path).to eq root_pathと記述すれば、今いるページがroot_path
hoverで、特定の要素にカーソルをあわせたときの動作を再現できる。
※ログイン機能を確認する場合は、buildではなくcreateであらかじめユーザーを作成する必要あり
ツイートの結合テストコード
have_selector
指定したセレクタが存在するかどうかを判断するマッチャ
検証ツールで要素を確認しとく
ツイート編集のテストコード
have_link
expect("要素").to have_link 'ボタンの文字列', href: "リンク先のパス"と記述することで、要素の中に当てはまるリンクがあることを確認できます
have_no_link
have_linkの逆で、当てはまるリンクがないことを確認します。expect("要素").to have_no_link 'ボタンの文字列', href: "リンク先のパス"
PicTweetにおいてこのhoverすべきクラスは.more
しかしながらログインしているユーザー以外のツイートも対象になってる
※誰が何をリクエストできるのかユーザー目線で考える
↓ findでなくallを使う
all
all("クラス名")でpageに存在する同名のクラスを持つ要素をまとめて取得できます。そしてall("クラス名")[0]のように添字を加えることで「◯番目のmoreクラス
ツイート削除テストコードの場合
find_link().click
a要素で表示されているリンクをクリックするために用います。find_link("リンクの文字列", href: "URL").clickといった形で使います。find().clickと似ていますが、find_link().clickはa要素のみに対して用いることができます。
ツイート詳細表示
コメントの結合テストに関しては、ツイートの結合テストと同様の記述
テストコード コントローラーまとめ
基本的にはページごとに
ユーザーがどんな操作をするか
どういう結果になるか(したいか)を全部ユーザー目線でexampleの整理して
それに伴うマッチャ(調べればOK)と記述(調べればモーマンタイ)をぶち込んで
ターミナルで動作できるか確認するだけ
サポートモジュール
RSpecにある メソッドをまとめる機能
重複してる記述をまとめられる