[Rails+Vue.js]に係るCRUD入門〜Part１：環境構築編〜

Rails+Vue.js+Webpackerによる「Create, Read, Update, Destroy」処理のチュートリアルを記述する。
なお，前提知識として，Railsチュートリアル終了程度を想定する。
# ＜概要＞
## ■ 本記事の内容
- チュートリアルに係る環境構築を実施する。
- [Rails+Vue.js]の基本的な動作を確認する。
- 今回のコードは，[GitHub](https://github.com/masayuki-0319/rails-vue-bookshelf/commits/master)の変更履歴で確認可能である。
    - [First Commit]から[ファイル構成修正（次回の準備）]まで
- 本記事の参考URL
    - [Rails 5.1 + Vue.js で開発を行う - part1 環境構築](https://qiita.com/cohki0305/items/582c0f5ed0750e60c951)
    - [Rails 5.1 + Vue.js で開発を行う - part2 Ajax で GET しよう！](https://qiita.com/cohki0305/items/a678b0b17c5b496c1de9)
    - [Vue.jsとRailsでTODOアプリのチュートリアルみたいなものを作ってみた](https://qiita.com/naoki85/items/51a8b0f2cbf949d08b11)
    - [webpack 4 入門](https://qiita.com/soarflat/items/28bf799f7e0335b68186)

## ■ 記事共通
- 目次
    - [ソースコード(GitHubへリンク)](https://github.com/masayuki-0319/rails-vue-bookshelf)
    - [▲ Part１: 環境構築編](https://qiita.com/Moo_Moo_Farm/items/afacfe4349af6a106253)：本記事
    - [〜Part２: Read編](https://qiita.com/Moo_Moo_Farm/items/fdf133d4c2bcf6d207b6)
    - [〜Part３: Vue Router設定編](https://qiita.com/Moo_Moo_Farm/items/075e970287cb1aaf52c1)
    - [〜Part４: Create, Update, Delete編](https://qiita.com/Moo_Moo_Farm/items/8cf46e228d59417550b1)
    - [〜Part５: Vuex設定編](https://qiita.com/Moo_Moo_Farm/items/fbc2e8c8f971dc5fe4bb)
    - [〜Part６: ユーザー登録&ログイン編](https://qiita.com/Moo_Moo_Farm/items/65aaa2ac7f8cef50fca6)
   - [〜Part Last: Docker化編](https://qiita.com/Moo_Moo_Farm/items/5975cd9d2d48ee35d6d6)

- 実装機能
    - お気に入りの本に係る登録，参照，編集，削除処理
    - 非同期通信（Ajax）による[Rails+Vue.js]のCRUD処理
    - SinglePageApplication（SPA）
    - ユーザー登録機能（JWTによるトークン認証）

- 開発環境
    - MacOS Mojave
    - Ruby(2.5.1)
    - Ruby on Rails(5.2.1)
    - Vue.js(2.6.10)
    - Yarn(1.17.0)
    - Webpack(4.39.2)

- 学習情報URL
    - [Vue.js公式](https://jp.vuejs.org/)
    - [Vue Mastery(The Vue Instance)](https://www.vuemastery.com/)


# ＜本文＞

## ■ 追記: 初期設定の自動化

`プロジェクトを生成`から`CSSフレームワークを導入（Materialize）`までの項目を自動化しました。

もし、入力が手間となる場合は、上記の手順を一部省略可能です。

- [Rails ジェネレータを使って初期設定を自動化しよう！ \- Qiita](https://qiita.com/Moo_Moo_Farm/items/ab755f10a9635be2af4d)


## ■ プロジェクトを生成
```.bash
$ rails new rails_vue_bookshelf --webpack=vue  --skip-test
```
- [--webpack=vue]：プロジェクト生成時にVue.jsを同時にインストールするオプション
- [--skip-test]：Minitestをインストールしないオプション（RSpecを想定）
- 参考URL
    - [小さく薄くrails newする(ViewやJSが必要ない場合)](https://qiita.com/shifumin/items/f4f4ea68d9963dbe9ca2)
    - [【Rails】generate コマンドで生成されるファイルをconfig.generatorsで設定する](https://remonote.jp/rails-config-generators)

## ■ バージョン管理(Git)の設定
```.bash
1. $ git init
2. $ git add -A
3. $ git commit -m "First Commit"
```

## ■ [rails generate]時の生成ファイルの設定
```config/application.rb
config.generators do |g|
  g.assets false
  g.helper false
end
```
- 参考URL
    - [rails generate で余分なファイルが生成されないようにする](https://numb86-tech.hatenablog.com/entry/2018/08/26/154619)

## ■ foremanによるサーバの設定
Vue.js（Webpack）を開発する際は，[rails server]とは別に[bin/webpack-dev-server]を立ち上げ，開発の都度２つのコマンドを実行することから，一つのコマンドで同時起動の設定をするため，Gem[[foreman]](https://github.com/ddollar/foreman)を使用する。

- 参考URL
    - [Introducing Webpacker](https://medium.com/statuscode/introducing-webpacker-7136d66cddfb)
    - [【動画付き】Rails 5.1で作るVue.jsアプリケーション ～Herokuデプロイからシステムテストまで～](https://qiita.com/jnchito/items/30ab14ebf29b945559f6#webpack-dev-server%E3%82%92%E6%9C%89%E5%8A%B9%E3%81%AB%E3%81%99%E3%82%8B)
    - [【Rails】foremanでrails serverとwebpack-dev-serverを一度に起動する](https://blog.yuhiisk.com/archive/2018/04/25/rails-and-webpacker-server.html)
    - [foreman で アプリケーションを動かす。](https://qiita.com/7kaji/items/6a59977d2ad85604e7fd)


**○１：Gemfileに追加**

```sh:Gemfile
group :development do
  ...
  gem 'foreman'
end
```

```.bash
$ bundle install
```

**○２：次のファイルを作成**

```Procfile.dev
web: bundle exec rails s
webpacker: ./bin/webpack-dev-server
```

```sh:bin/server
#!/bin/bash -i
bundle install
bundle exec foreman start -f Procfile.dev
```

- foremanを起動するには，３行目を実行するだけで十分であるが，ここでは，外部コマンド(シェルスクリプトによるプログラム)を設定し，楽にサーバを立ち上げられるように設定した。

**○３：パーミッションを変更**

```.bash
$ chmod 777 bin/server
```

- ここでは，[bin/server]コマンドがデフォルトで実行が出来ないことから，実行可能に変更するためのコマンドである。
- 気になる方は，上記コマンド実行前に[\$ bin/server]を実行し失敗して，[$ ls -l bin]コマンドでアクセス権を確認してみてください。
- 参考URL
    - [情報処理推進機構：第7章 データ漏えい対策最小のアクセスパーミッション](https://www.ipa.go.jp/security/awareness/vendor/programmingv2/contents/c602.html)
    - [Linuxの権限確認と変更(chmod)（超初心者向け）](https://qiita.com/shisama/items/5f4c4fa768642aad9e06)
    - [ドットインストール UNIXコマンド入門 [一般ユーザー編]
» #14, #15, #16](https://dotinstall.com/lessons/basic_unix_v2)

**○４：設定完了**

```.bash
$ bin/server
```

- http://localhost:5000 で[Rails default information page]（いつもの画面）が表示されたら成功
- [bin/server]：Procfile.devのコマンドを実行
- [Procfile.dev]：[rails s]と[bin/webpack-dev-server]を実行


## ■ CSSフレームワークを導入（Materialize）
Bootstrapでも良いが，本稿ではMaterializeを使用する。

```sh:Gemfile
gem 'materialize-sass'
gem 'material_icons'
```

```.bash
$ bundle install
```

```app/assets/stylesheets/application.scss
...
 *= require material_icons
 *= require_tree .
 *= require_self
 */
 @import 'materialize';
```

```app/assets/javascripts/application.js
...
//= require materialize
```

- 注釈：[.css]から[.scss]へ変更すること。
- 参考URL
    - [公式リファレンス](https://materializecss.com/)
    - [【Ruby on Rails】Materializeを導入する](https://kic-yuuki.hatenablog.com/entry/2019/02/25/091235)


## ■ 動作確認

**○１：Controller及びViewを生成**

```.bash
$ rails g controller Home index
```

**○２：View[index.html.erb]を修正**

```html:app/views/home/index.html.erb
<div id="app"></div>
<%= javascript_pack_tag 'hello_vue' %>
```

- [id="app"]：Vue.jsのデータをマウントするエントリーポイントの設定（RailsとVue.jsの接続部分）
- [javascript_pack_tag]：app/javascript/packs 配下にあるファイルの読み込み
- 参考URL
    - [Vue.js アプリケーションにおけるエントリーポイントの書き方メモ](https://qiita.com/shohei_ot/items/17c4c3545af9762d998e)

**○３：ルーティングの設定**

```config/routes.rb
Rails.application.routes.draw do
  root to: 'home#index'
end
```

**○４：動作確認**

```.bash
$ bin/server
```

- http://localhost:5000 で[Hello Vue!]が表示されたら成功

## ■ ファイル構成修正（次回の準備）
**○１：[hello_vue.js]を削除**
**○２：[application.js]を修正**

```app/javascript/packs/application.js
import Vue from 'vue'
import App from './App.vue'

const app = new Vue({
   el: '#app',
   render: h => h(App)
})
```

- [application.js]：このファイルをRailsと繋げるエントリーポイントとして設定する。
- [el:]：Railsのエントリーポイントとなる要素を指定
- [render:h =>h(App)]：importしたApp.vueを指定要素にレンダリング
- 参考URL
    - [Vue.jsのrender: h => h(App)について調べた](https://qiita.com/teinen_qiita/items/ed1bb1909a17f9ca9daa)


**○３：[app.vue]の名称及びディレクトリを修正**

```app/javascript/packs/App.vue
<template>
  <div id="app">
    <p>{{ message }}</p>
  </div>
</template>

<script>
  export default {
    data: function () {
      return {
        message: "Hello Vue!"
      }
    }
  }
</script>

<style scoped>
  p {
    font-size: 2em;
    text-align: center;
  }
</style>
```

- Mustache構文[{{ }}]：内部では[script]タグで定義したdataプロパティ等をテキストとして展開可能である（「1+1」や「message + '???'」のようにJavascriptの式も展開可能）。
- [data: function(){}]：Vueのdataプロパティやelプロパティは，全Vueインスタンスで同値が共有されることから，子コンポーネント側のdataプロパティは，オブジェクトではなく関数として定義する必要がある。
- 参考URL
    - [公式：テキスト（Mustache構文のこと）](https://jp.vuejs.org/v2/guide/syntax.html#%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88)
    - [公式：なぜ data は関数として必要なのですか？](https://jp.vuejs.org/2016/02/06/common-gotchas/#%E3%81%AA%E3%81%9C-data-%E3%81%AF%E9%96%A2%E6%95%B0%E3%81%A8%E3%81%97%E3%81%A6%E5%BF%85%E8%A6%81%E3%81%AA%E3%81%AE%E3%81%A7%E3%81%99%E3%81%8B%EF%BC%9F)
    - [公式：単一ファイルコンポーネント](https://jp.vuejs.org/v2/guide/single-file-components.html#ad)



## ■ Chromeに[Vue.js devtools]プラグインを導入
[Vue.js Devtools]は，Vue.jsの開発をサポートするChromeブラウザの拡張機能であり，dataの中身等の確認が容易になるため，導入することを推奨する。
使用方法は，Chromeデベロッパー・ツールから[Vue]タブを開く。

- 参考URL
    - [Vue.js devtools](https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?hl=ja&)
    - [Vue.js Devtoolsの導入方法と機能まとめ。Vue.jsを用いた開発を効率化させよう！](https://qiita.com/hashimoto-1202/items/c81f5d4c271eef16d957)

**〜Part１：環境構築編終了〜**
**[〜Part２：Read編へ進む〜](https://qiita.com/Moo_Moo_Farm/items/fdf133d4c2bcf6d207b6)**


## ■ [追記] 筆者の環境構築覚書
### □ Rubocop 設定
- 言わずと知れた Ruby のコーディング規約を強制させる静的解析ツール
- プロジェクトに参加するプログラマが，各々好きなコードの書き方をするとコードの可読性が損なわれるため，最低限のコードの書き方を強制させるために使用される。
- 規約は自由に設定できるが，デフォルトから設定するのは面倒であるため，[ruby/rubocop-airbnb](https://github.com/airbnb/ruby/tree/master/rubocop-airbnb)
や，[onk/onkcop](https://github.com/onk/onkcop)など，設定済みのライブラリを使用する。
- ここは，筆者の好みで Airbnb で設定する。

- 参考URL
  - [RuboCop is 何？](https://qiita.com/tomohiii/items/1a17018b5a48b8284a8b)
  - [Rubocopチートシート](https://qiita.com/tanish-kr/items/abb881c098b3df3f9871)
  - [Basic Usage - RuboCop: The Ruby Linter that Serves and Protects](https://docs.rubocop.org/en/latest/basic_usage/)

**○1： `Gemfile`に追加**

```:Gemfile
...
group :development, :test do
  gem 'rubocop-airbnb'
end
...
```

```bash
$ bundle install
```

**○2： 関連ファイル追加**

```yml:.rubocop.yml
inherit_from:
  - .rubocop_airbnb.yml
AllCops:
  TargetRubyVersion: 2.5
  TargetRailsVersion: 5.2

  # ここで解析しないディレクトリやファイルを設定可能
  Exclude:
    - 'bin/**/*'
    - 'config/**/*'
    - 'db/**/*'
    - 'lib/**/*'
    - 'node_modules/**/*'
    - 'vendor/**/*'
```

```yml:.rubocop-airbnb.yml
require:
  - rubocop-airbnb
```

**○3： 解析実行**

```bash:bash
# 基本コマンド
$ rubocop

# rubocop による解析結果を自動修正するオプション（修正されない箇所もあるため注意）
$ rubocop --auto-correct 
$ rubocop -a
```