Nginxって

Nginxって

  • webサイトを公開するとき、色々なサーバーが動いている中でそれらの中心で動いているwebサーバー

Nginxのメリット

  • 高速
  • 大量処理が得意
  • webサイト利用を向上させる機能が豊富
  • 設定は容易

Apacheのメリット

  • ossで無償で誰でも利用可能
  • cmsを動かすためのPHPやデータベースと連携がしやすい
  • モジュールにより基本機能が拡張可能
  • linuxだけでなくwindowsなど複数のサーバーOS上で利用可能

比較

  • 同時複数アクセスへの対処の仕方 Apache: 1アクセス = 1対応 Nginx: 複数アクセス = 1対応にまとめる

  • アクセス急増時のサーバーへの負荷 Apache: いっきに負荷増し Nginx: アクセスに比例して負荷が増えることはない

  • 上記の場合のwebサーバーの動き Apache: 遅くなりダウンする Nginx: 処理速度は維持し、ダウンしにくい

機能追加

Nginxを使う上でのデメリット

  • 大量の動的コンテンツの処理に不向き

    • 動画を中心に扱うwebサイトを運営する場合はApacheを選択するのが無難 動作方法の違いから
  • 専用のモジュールを追加すれば、ApacheだけでなくNginxも機能の拡張可能。

参考文献

Apacheとは?Webサーバーの仕組みと人気サーバーソフトを徹底解説 - カゴヤのサーバー研究室

ブランチモデル、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句での絞り込み

    - 「完全一致検索」であればインデックスが使われて高速化可能

    - 「部分一致検索」や「後方一致検索」では使えない

  1. order by句での並び替え

    - インデックスの並び替えも高速化可能 

  1. joinでの結合条件

    - joinでの結合処理は内部で並び替え処理を行なっているのでインデックスのある列を用いると高速化可能

参考文献

https://style.potepan.com/articles/25208.html

tail -f でlogを吐き出しながら開発

はじめに

今年の10月から晴れて駆け出しエンジニアになった坂本です。 業務の中での学びをアウトプットしていこうと思います。 あくまで私のアウトプットが目的なので至らない点があることを理解した上でご一読ください。

内容

今回はlogをターミナルで出力しながら開発することでデータがどういった道筋を辿ってviewにきているかを把握することができるメリットと方法をアウトプットしようと思います。

tail -f ~

tail -f log/[ファイル名].log

上記をターミナルで実行することでリアルタイムで出力することができます。 ※ ターミナルは別で立ち上げることをおすすめします。

メリット

個人開発では自身が書いたコードのためデータの流れを容易に把握することができますが、現場にjoinした際はコードもカラムもメソッドも量も質も桁違いなためデバックをするのも一苦労です。 そんな中、logを読みながらアプリをいじることでデータの動きを把握し、開発も素早く着手することができます。

logの読み方

logの読み方に関しては下記のブログを参考にしてみてください。

sprink.hatenablog.com

今後、開発を進める中で読み方のコツや躓いたポイントをアウトプットしていこうと思います。

最後に

実際に実務に入って約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

フック

コントローラーのアクションの前後に処理を差し込むことができる(コールバックと似ている) onlyexpectを付けることで特定のアクションに対して実行できる。 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
Railsenumを定義している時、自動でscopeが定義される
https://kossy-web-engineer.hatenablog.com/entry/2020/05/31/113615
RailsEnumってどんな子?使えるの?
https://qiita.com/ozackiee/items/17b91e26fad58e147f2e