Nginxって
Nginxって
- webサイトを公開するとき、色々なサーバーが動いている中でそれらの中心で動いているwebサーバー
Nginxのメリット
- 高速
- 大量処理が得意
- webサイト利用を向上させる機能が豊富
- 設定は容易
Apacheのメリット
比較
同時複数アクセスへの対処の仕方 Apache: 1アクセス = 1対応 Nginx: 複数アクセス = 1対応にまとめる
アクセス急増時のサーバーへの負荷 Apache: いっきに負荷増し Nginx: アクセスに比例して負荷が増えることはない
上記の場合のwebサーバーの動き Apache: 遅くなりダウンする Nginx: 処理速度は維持し、ダウンしにくい
機能追加
- リバースプロキシとロードバランサー
- webサーバーの負担を軽くして速度を上げる
Nginxを使う上でのデメリット
大量の動的コンテンツの処理に不向き
- 動画を中心に扱うwebサイトを運営する場合はApacheを選択するのが無難 動作方法の違いから
専用のモジュールを追加すれば、ApacheだけでなくNginxも機能の拡張可能。
参考文献
ブランチモデル、Git Flowについて
6つのブランチ
masterブランチ
- Gitでリポジトリを作成するとデフォルトでついてくるブランチ
- 基本的にマージ専用
developブランチ
- 開発の中心になるブランチ
- 基本的にここからブランチを切って作業しマージをする。直接コミットすることはない。
featureブランチ
- 機能の追加や変更、バグ修正を行うブランチ
- developブランチから派生させて開発後にdevelopブランチにマージする
- マージ完了後に削除するのが通例
releaseブランチ
- 製品をリリースするためのブランチ
- developブランチから切ってリリース作業を行う
- 完了後はdevelopブランチとmasterブランチにマージ
- masterブランチのマージコミットにリリースタグをを打つ
hotfixブランチ
- 重大な不具合が発生したときにmasterブランチから直接派生させて緊急対応
- developとmasterにマージしてリリースタグをうって終了
supportブランチ
- 旧バージョンなどの修正時に活用
- masterブランチから派生させる
■
インデックスとは
- テーブルにある情報を検索する場合に「どこに何があるか」をわかりやすく説明する索引のこと
- 索引があれば目的の情報を検索するときに効率よく探せる
- インデックスを作成すると元のテーブルとは別にテーブルを作ることになるので処理が2倍に
インデックスのメリット
- 検索パフォーマンスの向上
インデックスのデメリット
- データ追加、並び替え時の処理速度の低下
インデックスの作成方法
CREATE INDEX インデックス名(省略化) ON [ONLY] テーブル名 (カラム名...)
- 複数カラムの場合
CREATE INDEX インデックス名(省略化) ON [ONLY] テーブル名 (カラム名, カラム名)
インデックスの確認方法
- 「¥di」コマンドの活用
¥di テーブル名.*
- 「¥d」コマンドの活用 = インデックスの詳細を確認することができる
¥d テーブル名.インデックスカラム名
インデックスの削除
DROP INDEX インデックス名
#インデックスでクエリを高速化するパターン
- WHERE句での絞り込み
ORDER BY句での並び替え
JOINでの結合の条件
where句での絞り込み
- 「完全一致検索」であればインデックスが使われて高速化可能
- 「部分一致検索」や「後方一致検索」では使えない
- order by句での並び替え
- インデックスの並び替えも高速化可能
- joinでの結合条件
- joinでの結合処理は内部で並び替え処理を行なっているのでインデックスのある列を用いると高速化可能
参考文献
tail -f でlogを吐き出しながら開発
はじめに
今年の10月から晴れて駆け出しエンジニアになった坂本です。 業務の中での学びをアウトプットしていこうと思います。 あくまで私のアウトプットが目的なので至らない点があることを理解した上でご一読ください。
内容
今回はlogをターミナルで出力しながら開発することでデータがどういった道筋を辿ってviewにきているかを把握することができるメリットと方法をアウトプットしようと思います。
tail -f ~
tail -f log/[ファイル名].log
上記をターミナルで実行することでリアルタイムで出力することができます。 ※ ターミナルは別で立ち上げることをおすすめします。
メリット
個人開発では自身が書いたコードのためデータの流れを容易に把握することができますが、現場にjoinした際はコードもカラムもメソッドも量も質も桁違いなためデバックをするのも一苦労です。 そんな中、logを読みながらアプリをいじることでデータの動きを把握し、開発も素早く着手することができます。
logの読み方
logの読み方に関しては下記のブログを参考にしてみてください。
今後、開発を進める中で読み方のコツや躓いたポイントをアウトプットしていこうと思います。
最後に
実際に実務に入って約3週間、毎日四苦八苦しながらなんとかかんとか実装しています。 3ヶ月以内で1人で要件定義からリリースまで持っていけるよう頑張ります。 この記事がどこかで誰かの役に立てば幸いです。
attr_accessorでバリデーション
はじめに
今年の10月から晴れて駆け出しエンジニアになった坂本です。 業務の中での学びをアウトプットしていこうと思います。 あくまで私のアウトプットが目的なので至らない点があることを理解した上でご一読ください。
内容
今回は保存するmodelにバリデーションを設ける際にattr_accessorを経由させることで、保存するレコードの数を制御する。というテーマについて書いていこうと思います。
attr_accessorとは
下記のようなモデルクラスが定義されていたとします。
userモデル
class user def initialize(name, hobby) @name = name @hobby = hobby end sakamoto = User.new( '佐藤太郎' , 24 ) sakamoto.name end
通常、クラスの外部からインスタンス変数にアクセスしようとすると「メソッドが定義されていません。」と警告を受けます。 上記のコードもクラスで定義したメソッドに対してアクセスすることはできないので外部から再定義や変更を加えることはできません。
userモデル
class user attr_accessor :name, :hobby def initialize(name, hobby) @name = name @hobby = hobby end sakamoto = User.new( '佐藤太郎' , 24 ) p sakamoto.name end
しかし、同じクラスでもattr_accessorをクラスの中で定義してあげると先程のコードでも外部からクラス内部の情報に対してアクションを起こすことが可能になります。
つまり、クラス外部からクラス内部で定義されたメソッドに対して参照や変更を加えることができるようになるのがattr_accessorです。
バリデーションに生かす
上記の性質をもとにバリデーションに応用していこうと思います。 初めに書いたように今回は「1対多の親クラスから子クラスを制御するバリデーション」を組んでみようと思います。 下記のようなリレーションが組まれたモデルがあったとします。
userモデル
class User < ApplicationRecord has_many :hobbies, dependent: :destroy end
user_hobbyモデル
class Hobby < ApplicationRecord belongs_to :user end
userモデルに対してhobbyモデルが1対多の関係が組まれています。 ここまではよくあると思うのですが、ここから「userに対してhobbyは3つで抑えてね」と言われるとします。 この時に、
user_hobbyモデル
class Hobby < ApplicationRecord belongs_to :user validate :check_number_of_hobby def check_number_of_employees if hobby.count > 3 errors.add(:user, "3つ以上は入力できません。") end end
上記のように記述する方もいるのではないでしょうか? 私もこう書いてしまいました。 お気づきの方もいるでしょう。これだと一つのuser_hobbyテーブルのhobbyカラムに3つ以上レコードを入れることはできませんと言ってしまっているのです。 さらに、これだとuserクラスで定義されるはずのuserを参照することができないのでエラーになります。
ここでattr_accessor
今回の肝は「userモデルに対して3つまでしかhobbyテーブルは作れない」という点です。 つまり「hobbyテーブルでバリデーションをひいても意味がない」という解釈にたどりつけるか。という点が重要です。 保存されてくるレコードに対して1回1回バリデーションを当てはめていては、レコードの数を制御することはできません。 なぜなら1回1回保存されるのは1つのレコードのみなのでバリデーションが効かないからです。
なので今回の場合、「一度に保存されるレコードを一つのオブジェクトの中に代入し、バリデーションをかける」という作業をする必要があります。 以下のように、userモデルにattr_accessorで空のオブジェクトを生成してあげます。 さらにそのオブジェクトに対してバリデーションをひいてあげます。
userモデル
class User < ApplicationRecord attr_accessor :hobbies_count has_many :hobbies, dependent: :destroy validate :check_number_of_hobby def check_number_of_employees if hobbies_count.count > 3 errors.add(:hobbies_count, "3つ以上は入力できません。") end end
現状としては何も入っていないオブジェクトに対してバリデーションをかけている状態です。 このcheck_number_of_hobbyオブジェクトにコントローラーで保存するはずのレコードを配列で代入してあげることによって保存する前にレコードの制御を行うことができます。 attr_accessorを使ったのはモデル側で空のオブジェクトを生成し外部であるコントローラーでも活用でき、クラス内で定義したバリデーショにも生かすことができるからです。
最後に
現場では安易にレコードを保存させることはもちろん、保守性を意識し隙間を埋めるようなバリデーションをひかなくてはならないことを学びました。 今後も学んだことを少しづつアウトプットできたらと思います。
パーフェクトRails輪読会 ver7
2021年9月7日 パーフェクト Ruby on Rails
2-2-4
ルーティングとリソース
resources
resourcesメソッドとは、railsで定義されている7つのアクションのルーティングを自動で作成するメソッドです。 resourcesメソッドを使うことにより、簡単にルーティングを作成することができます。
id
を持つルートに限り
それぞれがid
を持った個人のページを持ち、URLに表記されるid
からページの場所を探してきます。resource
みんな一意のルーティングでページの場所は一緒になります。表示させる内容はそれぞれviewで変更しているだけです。
memberとcollectionの違い
どちらもルーティングをネストさせる時に用いますが、memberにはURLに
id
が含まれます。例えば、特定の投稿に対して、ブックマークする時などに使用します。
collectionはURLにid
を含みません。
- memberは特定のデータに利用する - collectionは全体のデータに利用する
例)
collectionは昼会でmemberは特定の誰かを指す。
2-3-4例外処理
何かしらのエラーが起きた時は基本的にRails側でよしなにやってくれているものですが、特定の動きをした時に行なって欲しい例外処理を自分で作ることができます。
そういった場合にはコントローラーにrescue_form
を使い記述します。
CSRF対策として、データの変更などのリクエスト時にセキュリティトークンも同時に発行し、それを検証することで自身のアプリケーションからのリクエストであることを証明する手法がとられています。
参照
2021年8月19日 現場Rails Chapterr6 (routes.rbについて)
https://morning-6.hatenablog.com/entry/2021/08/20/093820
パーフェクトRails輪読会 ver6
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