fv17の日記 - Coding Every Day

Webエンジニアの備忘用ブログです。主にWeb界隈の技術に関して書いています。

Railsの設計関連の記事まとめ

Railsの設計を学ぶ。
Railsに詳しい方々にコレ読みなさいと教えていただいたリンク集、と自分の学んだことメモ。

Ruby on Railsの正体と向き合い方

ポイント

  • Railsは小〜中規模開発に向いているが、どこかで限界が来る
  • 限界に対して、コード、アーキテクチャレベルで対処したい
  • 正体編では、「いつ、なぜ限界を迎えるのか?」を明らかにする
  • 向き合い方編では、既存の対処方法を俯瞰的な視点から捉えて提示する

Railsの正体

・DHHの設計思想:少人数のスタートアップでのプロダクト開発で「早くて綺麗」を実現
・それゆえのRailsのアプローチ:ModelのCRUD操作を中心にコードを整理して考える、書く量を減らす

限界について

・いつ: あるmodelが複数の異なるユースケースCRUD操作されるようになった時
・なぜ: あるmodelに書かれたValidations/Callbacksは特定のユースケースと密結合しているため

限界の表出の仕方

・特定の条件でValidations/Callbacksを実行 or スキップする
・Controller内に 'ApplicationRecord.transaction'を書く

限界との向き合い方

1.コードレベル:正面から解決するアプローチ

 ユースケース固有の処理を書く層を作り、共通処理のみModelに書く
 例:ActiveRecordの分割、Application Modelの導入、Form/Service(そのほか諸々のPORO)の導入

2.アーキテクチャレベル:そもそも回避しようとするアプローチ

 ・対象とするドメインを小さくする
 ・複数のサブシステムに分割する

レールの伸ばし方

ポイント

  • 人間が見て、一目で分かるようなコーディングにすべし!
  • 適切な抽象化をしよう

問題1: 1メソッドでごちゃごちゃ書いていて何しているか分からない

問題
  • 一目見て何をしているのか分からない
解決策
  • メソッドに切り分けて、一目で何をしているか分かるようにする

問題2: Fat Controller問題(Controllerの1アクションがカオス)

問題
  • 一目見て何をしているのか分からない
解決策
  • 基本的にロジックは全てモデルに任せる
  • Controllerの責務は以下の3つであると意識する

 ・モデルのメソッドを呼ぶ
 ・インスタンス変数への代入
 ・ビューの選択、もしくはリダイレクト先の選択

問題3: Fat Model問題

問題
  1. Model間の密結合により、複数モデルにまたがる処理が増える、修正の影響範囲が広くなる
  2. 複数レコードを扱う処理をクラスメソッドで書いてしまう
  3. 上記の結果、特定モデルに処理が集中し、行数が多くなり理解しづらい
解決策
  • POROに切り出す ex. PostWithNotificationsクラス

問題4: 大量のbefore_filter

問題
  • 一つのアクションで何が実行されているか分からない
  • 最終的にどんなインスタンス変数が設定されているか分からない
解決策
  • before_filterは使わず、各アクションからメソッドを呼ぶ
  • 呼び出したメソッド内部でインスタンス変数を設定せず、呼び出し側で設定する
  • インスタンス変数やプライベートメソッドが大量の場合は、ビューに渡す変数を抽象化

問題5: validationやcallbackの場合分け

問題
解決策
  • Form Objectで分割する

問題6: 一つのアクションでやることが大量

問題
  • 一目見て何をしているのか分からない
解決策
  • Serviceを導入し、アクションの詳細部分を担ってもらう

勉強方法を改善する

自分用メモ。
効率的に生きていくのに必要な知識、技術を身につけたい。

数学

これまでの間違った勉強法

  • 問題をまず5分前後解いてみる
  • 分からなければ解答を見て、再度解き直して覚える

上記における問題

  • 時間がかかり、学べる問題数が少ない

改良後の勉強法

  • 数学の肝は「解き方、解答に到るまでの流れを覚えること」
  • そのため、まず解き方を頭の中でアウトプット
  • 分からなければ、すぐに解答を見て解法を理解
  • 「解き方を頭の中でアウトプット」を繰り返し、記憶を定着

ポイント

  • 最初から解こうとしない
  • 「手で書いて、計算して答えを出す」のが勉強ではない

応用

  • プログラミング学習も全く同様
  • 実際にコーディングするのは、まず読んで理解して、記憶を定着させるフェーズで良い

Graphqlに入門するためのリンク集

公式Doc

Graphqlとは何か?
まず初めに読むべき公式DocとRubyによる実装方法。must read

GraphQL 本家
https://graphql.org/
GraphQL Ruby
https://graphql-ruby.org/

Github Graphql

パラメータ、戻り値、エラーハンドリング等々の主要な参考例
実際にGithubのGraphqlを叩すことができるため理解が深まる

Github Graphql Guides
https://developer.github.com/v4/guides/
Github Graphql Explorer
https://developer.github.com/v4/explorer/
Why GitHub is using GraphQL
https://github.blog/2016-09-14-the-github-graphql-api/

how to graphql - full stack tutorial

各バックエンド言語別の実装方法のチュートリアル
少し情報が古いかも

graphql-ruby Tutorial - Introduction
https://www.howtographql.com/graphql-ruby/0-introduction/

日本語で参考になるDoc

「GraphQL」徹底入門 ─ RESTとの比較、API・フロント双方の実装から学ぶ
https://employment.en-japan.com/engineerhub/entry/2018/12/26/103000
雑に始める GraphQL Ruby【class-based API
https://qiita.com/vsanna/items/031aa5a17a2f284eb65d
GraphQLにおけるエラーハンドリングの仕方
https://techblog.zozo.com/entry/graphql_error_handling

postgresの起動と接続

PostgreSQL

起動

cd /usr/local/var
postgres -D ./postgres/

終了

Ctrl + c

psqlコマンド

データベース一覧

\l
or
psql -l

データベースへ接続

psql -d <database name>
psql -d postgres

データベースから切断

\q 
or 
exit

テーブル一覧

\dt

テーブル構造

\d <table name>
\d users

例外処理を学ぶ

@jnchitoさんのまとめ記事
Railsアプリケーションにおけるエラー処理(例外設計)の考え方 - Qiita

@jnchiitoさんが学んだ、より詳細な記事
.NETの例外処理 Part.1 – とあるコンサルタントのつぶやき
.NETの例外処理 Part.2 – とあるコンサルタントのつぶやき
.NETの例外処理 Part. 3 – とあるコンサルタントのつぶやき
.NET の例外処理 Part. 4 – とあるコンサルタントのつぶやき
.NETとJavaの例外処理の違い – とあるコンサルタントのつぶやき

Rails - シングルテーブル継承(STI)とは

STIの詳細2(歴史、実例、代替方法、デメリットへの反論)

みんなRailsのSTIを誤解してないか!? - Qiita

ProsとCons

Pros

  • シンプルな実装
  • DRY
  • 必要に応じてサブクラスに独自の"振る舞い"を追加できる

Cons

  • データのメンテナンス性が下がり、不整合なデータが生成されがち
  • クエリパフォーマンスが下がり、検索が遅くなる

Consの理由

  • 開発が進み、モデル間で独自のカラムを持つようになると、あるモデルでは不要な項目となるため、データ上にnullが多くなる
  • 不要な項目を適切にnullにするためには、validationを厳格に行う必要があるが難しい
  • 運用が進みデータが溜まると、nullが存在する項目のクエリではパフォーマンスが悪くなる