2021年9月2日 パーフェクト Ruby on Rails
2-2-4
コールバックによる制御
必ず行いたい前処理や後処理を書けます。
before_○○○○○
ahter_○○○○○
around_○○○○○
←あんまり使わないかも
ログを残したい場合に条件を自分で設定し作成できます。
ログレベル
ログレベル | 名称 | 内容 |
---|---|---|
0 | debug | デバッグ情報など |
1 | info | 一般的な情報 |
2 | warn | 警告 |
3 | error | 制御可能なエラー |
4 | fatal | プログラムをクラッシュさせるような制御不可能なエラー |
5 | unknown | 常に記録されるべき不明なエラー |
logger(Rails.logger).leverで設定変更が可能。これは場所を問わない。これを書けば、ログが吐き出される。Railsの記載は省略でき、loggerからで良いです。
2-2-5
enum
数値のカラムに対して別名を与えます。なのでカラムを追加する必要があります。(もしくはmodelかmigrationファイルを作成する)
# db/migration内 add_column :hoge, :category, :integer, null: false, default: 0
# model内 enum category: { bug: 0, request: 1, others: 2 }
enumはモデルに対して定義する必要があります。
enumのメソッドでwhere.notはnotを記載する事で取得する事ができます。
# enumの書き方 Article.not_draft # これが取得できます。 Article.where.not(status: draft)
2-3-2
フック
コントローラーのアクションの前後に処理を差し込むことができる(コールバックと似ている)
only
やexpect
を付けることで特定のアクションに対して実行できる。
berore_action :hogehoge, only: [:show, :update]
フック一覧 | 処理が実行されるタイミング |
---|---|
before_action | Actionの実行前 |
after_action | Actionの実行後(正常にActionが実行された場合のみ呼び出される) |
around_action | Actionの前後 |
フックのスキップ
例えば、ログインが必要なアプリの時にApplicationControllerに操作を制御するフックを記載した場合、継承先のcontrollerに、skipのクラスメソッドを使用する必要があります。 そうしないと、いつまでもログインができないので注意が必要です。
CSRF適用を無効にしたい時の記述
特定のアクションのみセキュリティトークンの検証を行わないようにするには、下記のように記述します。
protect_from_forgery except: :update
複数のアクションで用いたい場合は配列で記述します。 ですが、基本的によほどのことがない限りセキュリティに穴をあけることになるので無闇に記述するのは辞めましょう。
ひとこと
around_action
なんて知らなかった。
参考
意外と知らないかもしれないRuby, Railsのメソッドとか
https://qiita.com/hc0208/items/45cce0f3f3c843c03c01#increment-decrement
Railsでenumを定義している時、自動でscopeが定義される
https://kossy-web-engineer.hatenablog.com/entry/2020/05/31/113615
【Rails】Enumってどんな子?使えるの?
https://qiita.com/ozackiee/items/17b91e26fad58e147f2e
2021年9月5日 図解入門 TCP/IP
1.2.2 プロトコルは階層で整理する
プロトコルで定義されている色々な通信機能は、その処理に応じて階層構造になっています。
1.2.3
TCP/IP参照モデル
4層構造になっています。
下の階層によって役割分担がされています。
自分の層の処理画終わったら他の層の処理には関与しません
階層 | 階層名 | 役割 |
---|---|---|
第4層 | アプリケーション層 | ユーザーに対して、アプリケーションを提供する |
第3層 | トランスポート層 | アプリケーションの識別と、それに応じた通信制御を行う |
第2層 | インターネット層 | 異なるネットワークにいる端末との接続性を確保する |
第1層 | リンク層 | 同じネットワークにいる端末との接続性を確保する |
私達的な覚え方・4321層の順番で頭文字を取って、アトイリと覚えます。
送る側 4 → 3 → 2 → 1 ↩️ 受信側 4 ← 3 ← 2 ← 1
層によってプロトコル(約束事)はたくさんあります!その辺はまた後で
OSI参照モデル
7層構造になっています。
TCP/IP参照モデルと同じで階層によって役割分担がされています。
こちらも自分の層の処理画終わったら他の層の処理には関与しません
|階層|名称|役割|
|----|----|----|
| 第7層 |アプリケーション層 |ユーザーに対して、アプリケーションを提供する|
| 第6層| プレゼンテーション層 |アプリケーションデータを通信できる方式に変換する|
| 第5層 |セッション層 |アプリケーションデータを送受信するため論理的な通信路(セッション)を管理する|
| 第4層 |トランスポート層| アプリケーションの識別と、それに応じた通信制御を行う|
| 第3層 |ネットワーク層| 異なるネットワークにいる端末との接続性を確保する|
| 第2層 |データリンク層| 物理層の信頼性を確保し、同じネットワークにいる端末との接続性を確保する|
| 第1層 |物理層 |デジタルデータを電気信号や光信号、電波に変換して、ネットワークに流す|
覚え方、7654321層の順の頭文字で、アプセトネ デブと覚えます。
PDUとは (Protocol Data Unit)
各階層で処理されるひとまとまりのデータ、つまりデータの単位のこと。
私たちなりの例え
本書で使用するモデルは以下のように二つのモデルをいいとこどりした5階層のものです。
各階層別のPDUの名称
階層 | 名称 | PDUの名称 |
---|---|---|
第7層 | アプリケーション層 | メッセージ |
第4層 | トランスポート層 | セグメント(TCPの場合)、データグラム(UDPの場合) |
第3層 | ネットワーク層 | パケット |
第2層 | データリンク層 | フレーム |
第1層 | 物理層 | ビット |
- 今日の覚えること
アトイリ
アプセトネ デブ
参考
本書のみ
2021年9月4日 図解入門 TCP/IP
プロトコル(通信プロトコル) ネットワークの世界で、パケットを処理するときの約束事
プロトコルで決まっていること
- 物理的な仕様 LANケーブルの素材やコネクタの形状、そのピンアサイン(ピン配列)に至るまで、ネットワークにおいて、目に見えるものは全てプロトコルで定義されています。
送信相手の特定 ネットワークの世界で、現実の世界と同じように住所を割り当てて、送信相手を区別しています。
パケットの転送 細かく分けたパケットを相手に送るためにヘッダーにはどんな情報があってどんな順序でやりとりするかが定義されています(たくさんの情報が入っている) そのパケットを届けるために自分と相手のコンピューターの間にあるネットワーク機器がヘッダーを見てバケツリレーの様に転送していきます。
信頼性の確立 パケットは世界中に張り巡らされたネットワークに乗って、ありとあらゆるところを駆け巡っているので、いつどこでどんなときにパケットが壊れたりなくなったりするかわかりません。それでも大丈夫なようにエラーを通知したり、データを再送したりする仕組みを提供しています。また、有限なネットワークリソースがパケットでいっぱいになって、溢れてしまわないための仕組みも提供しています。 通信が多くなる時間帯に通信が重くなったりするのは、限られたネットワーク帯域をみんなで共有できるように、ネットワークで制御されている為です。
セキュリティの確保 プロトコルは、重要な情報を安心してやり取りできるように、正しい通信相手であるか認証し、通信を暗号化する仕組みを提供しています。ログインの時はwebブラウザが接続先のサーバーが正しい通信相手であるかをしっかり確認した後、ユーザー名とパスワードを暗号化して送信します。
ここまでまとめ
プロトコルとは … 約束事の名称
パケットという小分けにしたデータを安全に処理するための約束事
例えてみました
プロトコルはネットワーク上での、交通ルールで、これを守るから事故などを起こさずに送ったものを届けることができる。信号があったり、時には渋滞もするから、送信に時間がかかる事態にもなるが、それは安全に届ける為に交通ルールを守っている為です。ヘッダーは伝票に当たるものだと思います。伝票に相手の住所を記載してあるから、送信者も受信者もその届け先が合っていると判断できると思います。
参考
本書のみ
2021年9月3日 図解入門 TCP/IP
1.1.1 ネットワークの歴史
ネットワークの原型は一台の大型コンピュータとみんなで使用するTSS(Time Sharing System)という方式でコンピュータを使用していました。遠隔地にいるユーザーはTSS端末から大型コンピュータに電話でアクセスし、あたかも自分専用のコンピュータであるかのように扱うことができました。
TSSにより、大型コンピュータとTSS端末の2台だけで構成される最もシンプルなネットワークができたのが、ネットワークの始まりです。
APANET 超重要なネットワークで、インターネットのルーツです。
- パケット ... 小さく分けたデータの単位
- パケットのやりとりをパケット交換方式という
1.1.2 回線交換方式とパケット交換方式
回線交換方式
固定電話をイメージ。相手が話しても話さなくても電話を切るまで繋ぎっぱなし。
パケット交換方式
必要な時だけ必要な分だけパケットを送る。パケットにはヘッダーをくっつける。
ヘッダー 送信側のコンピュータはデータにつける情報です。宛先となるコンピュータの情報だったり、データの何番目に当たるパケットなのかだったり、様々な情報が含まれます。
パケット交換ネットワーク ヘッダーの情報を見て、宛先のコンピュータにパケットを送り届けます。また、宛先コンピュータはヘッダーの情報を見て、元のデータに復元します。
例: ニトリで家具を買い、家で組み立てる組み立ての説明書がヘッダーです。
参考
本書のみ
2021年9月2日 パーフェクト Ruby on Rails
SQLite3ではnot null制約を付与しつつカラムのデフォルト値を指定しない場合、カラムの追加でエラーになってしまいます。
例)
# NG class AddNicknameToUsers < ActiveRecord::Migration[6.0] def change add_column :users, :nickname, :string, null: false end end # OK class AddNicknameToUsers < ActiveRecord::Migration[6.0] def change add_column :users, :nickname, :string, null: false, default: 'sample' end end # OK class AddNicknameToUsers < ActiveRecord::Migration[6.0] def change add_column :users, :nickname, :string change_column :users, :nickname, :string, null: false end end
パーフェクト Ruby on Rails p60の例での説明
2-2-2
# 2xxxxxxxxxxxxx_add_publisher_id_to_books.rb 略 def change add_reference :books, :publisher, foreign_key: true #rails g migration時にreferencesをつけた事により外部キーであるforeign_keyが生成されており、この行でpublisher_idが作られます。(注:publisher_idとこの行で書いてしまうとpublisher_id_idとなってしまいます。) change_column :books, :publisher_id, :integer, null: false #ここで1行目に生成されたpublisher_idにnull: falseをつけることでnot null制約を付与しています。
rails c 内でのreloadとは
reloadメソッドとは、データベースに保存されているもともとのレコードをリロードすることです。
以下、検証結果です。
irb(main):021:0> user = User.new(last_name: '田中', first_name: '花子', password: 'password', password_confirmation: 'password', email: 'sample@sample.com' ) => #<User id: nil, email: "sample@sample.com", crypted_password: nil, salt: nil, created_at: nil, updated_at: nil, last_name: "田中", first_name: "花子", avatar_image: nil, reset_password_token: nil, reset_password_token_expires_at: nil, reset_password_email_sent_at: nil, access_count_to_reset_password_page: 0, role: "general"> irb(main):022:0> user.reload Traceback (most recent call last): 1: from (irb):22 ActiveRecord::RecordNotFound (Couldn't find User without an ID') irb(main):023:0> user.save (0.1ms) begin transaction User Exists (0.6ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = ? LIMIT ? [["email", "sample@sample.com"], ["LIMIT", 1]] User Create (1.0ms) INSERT INTO "users" ("email", "crypted_password", "salt", "created_at", "updated_at", "last_name", "first_name") VALUES (?, ?, ?, ?, ?, ?, ?) [["email", "sample@sample.com"], ["crypted_password", "$2a$10$FFT.hUH/PZI5ae5ajqeLUe1kM.H0AWS/mJV0.ZIKJo1ev7N1JcDMC"], ["salt", "FNGVQWhJLc3N-nHWvs9H"], ["created_at", "2021-09-03 16:04:23.608038"], ["updated_at", "2021-09-03 16:04:23.608038"], ["last_name", "田中"], ["first_name", "花子"]] (1.1ms) commit transaction => true irb(main):024:0> user.reload User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 15], ["LIMIT", 1]] => #<User id: 15, email: "sample@sample.com", crypted_password: "$2a$10$FFT.hUH/PZI5ae5ajqeLUe1kM.H0AWS/mJV0.ZIKJo1...", salt: "FNGVQWhJLc3N-nHWvs9H", created_at: "2021-09-03 07:04:23", updated_at: "2021-09-03 07:04:23", last_name: "田中", first_name: "花子", avatar_image: nil, reset_password_token: nil, reset_password_token_expires_at: nil, reset_password_email_sent_at: nil, access_count_to_reset_password_page: 0, role: "general"> irb(main):025:0>
SQLiteの出力モード
- line : 1行ずつ表示。
- html : html形式で表示。
- tabs : 各列をタブ区切りで表示。
- csv : 各列をカンマ区切りで表示。
2-2-3
結論 「バリデーション + データベースでの制約」どっちも必要、安全!!」 Race Conditionが起きないように!!
Race Condition レースコンディションとは、複数の処理が同じデータに同時にアクセスした場合に、機能停止など予期しない処理結果が生じてしまうことです。 つまり 同時にアクセスなどしたときにバリデーションをすり抜ける可能性があるため二重ロックの意味でもバリデーションだけでなくnot null制約もつけるべきです。 バリデーションはDBに渡る前のActiveRecordの段階で制御し、not nullはDBに渡ってからDBで制御されます。
バリデーションヘルパー
ActiveRecord/ActiveModelの機能を使用したバリデーションです。(presence: trueなど)
validates :price, numericality: { greater_than_or_equal_to: 0 }の内訳
numerucality
は数値であること、オプションでゼロ以上、偶数かどうかなどを検査します。greater_than_or_equal_to: 0
はゼロ以上であること >=
と同義です。
バリデーションでpresence: trueが無く、DBでNot NULL制約がある場合DBには保存はされない。
エラーメッセージを表示したい場合はインスタンス.errors.messageまたはインスタンス.errors.full_messageを記述すると良い。(errorsはメソッド)
メソッドに!
をつけるかつけないか
!
をつけないとバリデーション失敗時に例外を起こさない
!
をつけると失敗時に例外を起こす
nullとnil
nilはrubyの言語。nullの意味。
-nilでもメソッドのエラーを出したくない時は&.
ぼっち演算子を使います。
参考文献
reloadメソッド
https://k-koh.hatenablog.com/entry/2020/12/28/214557
Race Condition
https://enterprisezine.jp/securityonline/word/detail/%E3%83%AC%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%B3%E3%83%87%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%B3
2021年9月2日 パーフェクト Ruby on Rails
第2章 Ruby on RailsとMVC
2-1 MVCアーキテクチャ
- M(Model)
- データベースとの接続
- V(View)
- 視覚表現を行う部分
- C(Controller)
- ModelとViewをつなぐ部分
2-1-2
モデルの役割 - データベースと接続し、データベースのレコードをActive Recordオブジェクトを結びつける役割(Active Record) - バリデーションや、レコード保存時などに実行する様々なコールバックなどを実行する役割。(Active Modelが担っている)
Active Record
RailsにはModelにActiveRecordが適用されているおかげで、Rubyを用いてDBからデータを探したり、持ってきたりすることができます。
- Active Recordがあるおかげでcreate
やnew
,find
,all
…などのメソッドが使うことができます。
生のSQLを書かなくていい様にしてくれています。
Active Model Active Recordの多くのモジュール含むライブラリです。
Actioin Pack MVC のうち View と Controller を司るのが ActionPackというライブラリです。
MVCのモデルとは
あるシステムを作るという事は、そのシステムが解決する問題に対して必要な概念を探して、名前を付けたり相互の関係性を整理したりする事であり、その行為をモデリングと呼び、これがMVCのモデルです。
CRUD
データベースのレコードに対する基本的な操作のことです。 Create、Read、Update、Delete
※ Readはデータに影響を与えないので参照系、それ以外はデータに影響を与えるので更新系です。
2-2 モデルを扱う
モデルを通じて検索を行う = Railsの書き方でSQL検索
2-2-1
- データベースに登録されているレコードを一件だけ検索
- findメソッド : idを使用してレコードを取得
- 検索結果が見つからないと
Activerecord::RecordNotFound
例外が発生
- 検索結果が見つからないと
- find_byメソッド : id以外を使ってレコードを取得
- 検索結果が見つからないとnilを返す
- findメソッド : idを使用してレコードを取得
- 複数件のレコードを検索する場合
- whereメソッド
- データが存在しない時は
ActiveRecord::Relation
インスタンスが返る
- データが存在しない時は
- whereメソッド
ActiveRecord::Relation
- SQLのそれぞれの表現に対応したメソッドをチェーンみたいに繋げていくことが可能です。(例:
Book.where("price>?", 3000).limit(3).order(:name)
みたいな感じ) - 実行結果のデータを普通の配列と同じような感覚で扱えます。
メソッドチェインを使うメリット
必要以上にデータベースとの通信が発生してしまうのを防ぐ効果があります。また、処理の流れを明確にできることがあります。 非同期処理を挟まない限り、前から後ろに向けて順番に処理されます。処理がメソッドチェインの各スコープの中で完結するため、一時変数を定義したり命名する手間が省けます。
Query Interface
Active Recordのメソッド(select、where、limitなど)のこと。
クエリ
「問い合わせ」。データベースに対する命令文のことです。
SQLは「言語」でクエリ(SQL文)は「命令(文)」です。
scopeの定義
よく利用する検索条件に名前をつけてひとまとめにしたもの (例:名前を"物件の条件"とした場合、内容を"バス・トイレ別, 室内洗濯機置き場"などにし、その後"物件の条件"という名前で呼び出せば、毎回内容を記載する必要がないため使い回しに便利です。)
scope :高級物件, -> { where("家賃 > ?", 100,000円)} scope :トイレ, -> (toilet){ find_by(toilet: toilet) }
トイレのscopeを例にするとトイレがない場合はActiveRecord::Relation
が返る。。
scopeで定義した場合は結果がnilでもActiveRecord::Relation
を返します。もしnil
を返したい場合はクラスメソッドとして定義したほうが良いです。
クラスメソッド
モデルで定義するメソッドのことです。
User.hoge # クラス名.クラスの中にあるメソッド名 で呼び出す class Home def self.toilet(toilet) Home.find_by("あるよ") puts "トイレつきだあ" end end Home.toilet("あるよ") => トイレつきだあ Home.toilet("ないよ") => nil
参照
Active Record https://qiita.com/ryokky59/items/a1d0b4e86bacbd7ef6e8
Action Pack https://magazine.rubyist.net/articles/0008/0008-RubyOnRails.html
クエリとは https://wa3.i-3-i.info/word11290.html
scopeとクエリについて https://qiita.com/ozin/items/24d1b220a002004a6351
クラスメソッドとは https://qiita.com/right1121/items/c74d350bab32113d4f3d
2021年8月31日 パーフェクト Ruby on Rails
1-4-4
http://localhost3000/rails/info/routes
にアクセスすると現在のルーティング情報が表示されます。
- コントローラー内で定義されたpublicメソッドのことをアクションと呼びます。
- (:format)
- Prefix
- 番号や符号、識別名などの先頭部分に付加し、何らかの意味や情報を表す短い部分のこと
「変数名のプレフィックスは『sayo_』にすること」というルールがあったとしましょう。
その場合、変数の名前を「sayo_a」や「sayo_b」のようにします。 変数名の前に必ず「sayo_」を付けるわけです。
このように、その単語なり何なりの前にくっつける文字列がプレフィックスです。
PUTとPATCHの違い
- PUT
- リソースそのものの更新
- PATCH
- リソースの部分の置き換え
ユーザー名を更新する時などは部分更新なのでPATCHを使用します。
RESTとRESTful RESTとはルール(原則) RESTfulはRESTのルールに沿って開発されたWEBシステム
RESTの原則統一インターフェース:あらかじめ定義・共有された方法(WebであればHTTP)で情報がやりとりされるアドレス可能性:すべての情報が一意なURLの構造で示される接続姓:やりとりされる情報にはリンクを含めることができるステートレス性:やりとりは1回ごとに完結し、前のやりとりの結果に影響を受けない
ActionCableの場合RESTfulなの?
WebSocketをActionCableで使うとrubyで記述することができるようになり、RESTfulの思想を受け継ぎ実装することができます。
1-4-5
一章のまとめ
ルーティングでURLとコントローラ内のメソッドをひも付ける事でURLに対するアクションを定義し、そのアクションの中でモデルを通じてデータを取得します。そして、そのデータを元にテンプレートファイルを通じてHTMLを生成、描画しています。
参照
prefix https://e-words.jp/w/プレフィックス.html
プレフィックスとは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典 https://wa3.i-3-i.info/word1208.html
(:format)とpatchとputの違いについて https://books.google.co.jp/books?id=VCFHDwAAQBAJ&pg=PA59&lpg=PA59&dq=URLの拡張子 (:format)&source=bl&ots=Ex3ZaViTRj&sig=ACfU3U0lLws9wQ034U2d5e9nGkLQG8p_4g&hl=ja&sa=X&ved=2ahUKEwiIlceh0dryAhWKGaYKHWWlCUg4ChDoAXoECAwQAw#v=onepage&q=URLの拡張子 (%3Aformat)&f=false&source=bl&ots=Ex3ZaViTRj&sig=ACfU3U0lLws9wQ034U2d5e9nGkLQG8p_4g&hl=ja&sa=X&ved=2ahUKEwiIlceh0dryAhWKGaYKHWWlCUg4ChDoAXoECAwQAw#v=onepage&q=URL%E3%81%AE%E6%8B%A1%E5%BC%B5%E5%AD%90%E3%80%80(%3Aformat)&f=false)