Railsでポートフォリオを作成する際に押さえたいこと

# はじめに
近年エンジニアの需要が伸びておりプログラマーとして転職や就職をされる方が増えています。
そんな中で転職用にポートフォリオを作成される方が多いと思いますが、今回はそんな初学者がRailsでポートフォリオを作る際に押さえたいことをまとめました！
転職活動中の方や新卒で就職を考えている方はもちろん、Railsで初めてアプリを作る！なんて方にも参考にしていただけると思います！

コメントいただいた内容を元に一部修正しております。

# Railsの基本理念について改めて理解する。
いろんなサイトでもよく取り上げられていますが、railsには大きく２つの基本理念があります。
[Rails Guides](https://guides.rubyonrails.org/getting_started.html#what-is-rails-questionmark)
[Rails Guides日本語訳](https://railsguides.jp/getting_started.html#rails%E3%81%A8%E3%81%AF%E4%BD%95%E3%81%8B)

・DRY (Don't Repeat Yourself)
　　同じことを繰り返すな
・CoC (Convention Over Configuration)
　　設定より規約が優先される

おそらく学び始めの頃に見たことがある方も多いのではないでしょうか？
基本理念についてあまり理解せずに進めてしまうとせっかく時間をかけて作ったあなたのポートフォリオが微妙になってしまう可能性があります:sob:
イカしたポートフォリオを作るためにもここで一つずつ確認していきましょう！

### DRY 同じことを繰り返すな
これについては理解されている方も多いと思いますが、同じことを繰り返して記述してしまうと以下のデメリットが生まれます。
・単純にコード量が増えてしまう。
・複雑なロジックなどの場合、同じ処理であることに気がつきにくくなるなど可読性が下がる。
・変更を加えた場合に修正箇所や確認箇所が増える。
など
Rails以外にも言えることですが、何度も記述しているものは変数に代入したり、メソッド化して繰り返し使えるようにしましょう。

### CoC 設定より規約が優先される
（@scivolaさんよりいただいたコメントを参考に修正いたしました）
ここでの規約とはRailsのフレームワークとしての設計で定められた規約になります。
例えば、Rails コマンドであるscaffoldで生成されるものについては以下のものがあります。

```:ターミナル
rails g scaffold User

      invoke  active_record
      create    db/migrate/xxxxxxxxxxxxxx_create_users.rb
      create    app/models/user.rb
      invoke  resource_route
       route    resources :users
      invoke  scaffold_controller
      create    app/controllers/users_controller.rb
      invoke    erb
      create      app/views/users
      create      app/views/users/index.html.erb
      create      app/views/users/edit.html.erb
      create      app/views/users/show.html.erb
      create      app/views/users/new.html.erb
      create      app/views/users/_form.html.erb
      invoke    helper
      create      app/helpers/users_helper.rb
      invoke    jbuilder
      create      app/views/users/index.json.jbuilder
      create      app/views/users/show.json.jbuilder
      create      app/views/users/_user.json.jbuilder
      invoke  assets
      invoke    scss
      create      app/assets/stylesheets/users.scss
      invoke  scss
      create    app/assets/stylesheets/scaffolds.scss
```

コマンド入力後のファイルを確認するとapp/controllers/users_controller.rbには
`index, show, new, create, edit, update, destroy`の７つのアクションが生成されており、
config/routes.rbには`resources :users`が書き足されています。
app/views/userフォルダの中には同じくアクションに対応した`index, show, new, edit`のhtml.erbファイルが生成されています。
これらの内容だけでModelに対して一連の動きができるようになっています。
resourcesについてはシンボルで渡したコントローラ名に対応するリソースフルルーティング([参考ページ](https://railsguides.jp/routing.html#crud%E3%80%81%E5%8B%95%E8%A9%9E%E3%80%81%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3))を生成したり、controllerのアクションについては特別なことをしない限りアクション名と同じ名前のviewファイルを読みに行くなど設定を書かずとも動くようになっています。これらの機能がCoCでいう規約に基づいています。
他にもModel名を単数形で設定し、データベースのテーブル名を複数形に設定するだけでModelとの連携が機能するなどがあります。
もしこれらの規約から外れてしまう場合、その都度設定のコードを増やしてしまいます。
そのため規約どおりでなければ実装できないなどの場合以外は規約から外れないアプリケーション設計を心がけましょう。

# Rails アプリの開発者が心がけるべき指針
簡単にいってしまえば整理整頓だと僕は思っています。
コードが散らかっていては他の人が見たときにどこに探しているコードがあるのかわかりませんよね！
コードの内容によってどこに記述するのか決められていると他の人でもコードが追いやすくなります。
ただ、整理整頓するにも多少知識が必要になります。
## MVCモデルについて

#### Model
アプリケーションのデータの処理について主に記述する。
データの処理とはDBからデータ取得や取得したデータの加工、Modelに紐づくDBのテーブルについての変更など

#### View
アプリケーションのユーザインターフェースを定義する。
ユーザーとアプリケーション間でレスポンスをするデータの整形を行う。

#### Controller
送られてきた情報(URLやパラメータなど)を元にModelにデータを要求したり、Viewにデータを渡したりする。
レストランでいうウェイトレスやサーバーのようなことをしてくれる部分

上記が大体の役割になります。
ここで気をつけて欲しいのがControllerやViewはデータの加工を行わないということ！

```Ruby:users_controller.rb
User.all
User.new
User.destroy
```

などについてはあくまでクラスメソッドを呼び出しているだけであるため問題はないですが、

```ruby:users_controller.rb
# このようなクエリインターフェースなどはscopeに書きましょう
@users = User.where("old > ?", 20).order(name: :desc, :created_at)

# このようなロジックはクラスメソッドやインスタンスメソッドなどに書きましょう
@latest_update_book = @user.books.order(:updated_at).last
```

以上の内容については本来controllerに記述するべき内容ではないためきちんと分けましょう。

```ruby:user.rb
# bookモデルと1対多の設定です。
has_many :books

# 修正例
scope :desc_adult_at_name, -> { where("old > ?", 20).order(name: :desc, :created_at) }

def latest_update_book
  books.order(:updated_at).last
end
```

```ruby:users_controller.rb
@users = User.desc_adult_at_name
@user.latest_update_book
```

他にもポートフォリオではあまり用いることは無いかもしれませんがtaskであったり、service、decoratorなど今後触れる機会があるかもしれませんのでそれぞれの役割について余裕があれば調べておくといいと思います！

# セキュリティ面について意識する
### URL直接入力による画面遷移など
よく初学者の方が忘れがちになることがURLの直接入力の対策だと思います。
例えば以下の変更により他のユーザーの購入履歴画面や編集画面に遷移できてしまう事例です。

```ruby:users_controller.rb
class UsersController < ApplicationController
  before_action :correct_user, only: [:edit]

  def edit
    @user = User.find(params[:id])
  end

  private
  def correct_user
  # 書き方は色々あると思いますが、、、
    redirect_to root_path if current_user.id != params[:id].to_i
  end
end
# ログイン中のユーザーIDを１だとします。
current_user.id
=> 1

# 上記のbefore_action, correct_userなどの処理が抜けていた場合
# 下記のURLを直接入力すると関係ないユーザーの編集画面に飛べてしまう
localhost:3000/users/2/edit
```

この事例については知っていても実装を忘れてしまっている方も多いと思います。
before_actionやgemの[banken](https://github.com/kyuden/banken)などを利用して対策しましょう！

### XSS(クロスサイトスクリプティング)
[XSSとは](https://railsguides.jp/security.html#%E3%82%AF%E3%83%AD%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%88%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0-xss)
よく見るのはtext_fieldやtext_areaなどからscriptタグを入力されてしまい、セッションなどを取られてしまうなど不正な操作を行われてしまうなどかと思います。
文字だけ見ればとても怖いですが、対策はとても簡単で[SanitizeHelper](https://edgeapi.rubyonrails.org/classes/ActionView/Helpers/SanitizeHelper.html#method-i-sanitize)などを利用すれば簡単にサニタイズすることができます。
なにかユーザーが入力したデータをそのまま表示する場合などにかけるといいと思います。

他にもSQLインジェクションや、CSRFなどの攻撃が存在するため調べてみることをお勧めします。
# 静的解析ツールを使用してコードを綺麗に保つ
静的解析とはコードを実行せずに解析を行うもので、主に記述ミスなどの検出によりエラーを回避したり、コーディングルールをチェックし、全体の保守性を向上させる役割があります。
rubyには[rubocop](https://github.com/rubocop-hq/rubocop)という有名な静的解析ツールがあります。
ポートフォリオで利用する必要はあまりないと思われるかもしれませんが、現在Railsを利用しているプロダクトではほとんど利用されているためツールを使う習慣が身につきやすい点であったり、コードもコーディングルールによって見やすくなるため結果的に綺麗なコードになりやすいです。
ポートフォリオは見てもらうアプリですから、アプリを公開していたとしてもコードも見られますので綺麗なコードを書く癖を今からつけましょう！

# testを書こう
テストを書きましょう！
ポートフォリオなどを作っているタイミングではテストを書いたことがある人は少ないと思いますが、実際にエンジニアとして働くと大体クラスメソッドやserviceクラスなどを作成した際にはテストを書きます。スタートアップなどスピード感を重視している場所などによってはテストを書く文化があまりない場所もあるかもしれませんが、基本的にはテストは必須になってきます。
つまり、エンジニアになると嫌でもテストを書く必要が出てきます。
静的解析ツールと同じで今からテストが書けるように習慣付けましょう！
テストにも種類がありますが、ポートフォリオではメソッドなど機能を小さく切り分けテストするユニットテストを書きましょう！
RailsのテストフレームワークとしてRspecが主に使われていますのでRspecを使用することをオススメします！
Rspecの書き方については[この記事](https://qiita.com/jnchito/items/42193d066bd61c740612)がとても参考になります。

# まとめ
いかがだったでしょうか？
通常プロダクトを開発する際には初めに技術選定行い、その時にベストな言語などを選択している企業がほとんどです。
あなたが狙っている企業がもしRailsを使用していた場合など、Railsの理念に沿った書き方(The Rails Way)ができているかどうかはとても重要な確認ポイントだと思います。
書き方がわからないという場合は[rails best practices](https://github.com/flyerhzm/rails_best_practices)というgemを利用するのも一つの手だと思います。
もしポートフォリオをすでに作成されている方はこの書き方が出来ているかリファクタリングを行ってみてもいいと思います。

また、最近人事の方にお会いすることが多いため 「ポートフォリオでよく確認するところはどこか」と聞いてみたところ大体の方がコードが綺麗か、転職者であればtestはかけているか、といった所を見る方が多かったです。

より実践的なコードを書いて他の求職者の方とポートフォリオで差をつけましょう！

間違えている箇所や補足などあればぜひコメントをいただけると泣いて喜びます:joy:

# 参考文献
- [Rails Guides](https://guides.rubyonrails.org/getting_started.html#what-is-rails-questionmark)
- [Rails Guides日本語訳](https://railsguides.jp/getting_started.html#rails%E3%81%A8%E3%81%AF%E4%BD%95%E3%81%8B)
- [使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」](https://qiita.com/jnchito/items/42193d066bd61c740612)