Rails 5.2 で簡単なWikiサイトを作る

# はじめに

**社内問い合わせに、日々困ってませんか？**
私は、ほとんど同じ内容を同じ人や、同じ部署の人からチャットや、電話、直接話しかけこられ、とっても困っていました。簡単に導入できそうなサービスも見つからず、困ったので作ってみたいと思います。

[![Heroku Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy?template=https://github.com/fukmaru/wiki)

# 環境

- `Rails 5.2.2`
- `ruby 2.5.1p57`
- `psql (PostgreSQL) 10.4`

# 前提条件

本記事では、Rails、ruby、PGのインストールの内容を含みません。

- ruby のインストールは、[こちら](https://qiita.com/Alex_mht_code/items/d2db2eba17830e36a5f1)の記事がわかりやすかったです。
- Ruby on Rails のインストールは、[こちら](https://qiita.com/yoshiokatsuneo@github/items/d75d4fef9e75afb65126#rails%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)の記事がわかりやすかったです。

# 工程

1. Railsのベースアプリを作る （本記事）
- [Active Record マイグレーションでコンテントデータベースを作る](https://qiita.com/fukmaru/items/cca06609157d2223af6f)
- [一覧を作る](https://qiita.com/fukmaru/items/318bc4ef1fa5b80e4c9a)
- [コンテンツ登録・変更・閲覧ができるようにページを作る](https://qiita.com/fukmaru/items/9f59511463dded5e0ec1)
- [検索機能を実装する](https://qiita.com/fukmaru/items/c22ba2700e9ad368770c)

# Railsのベースアプリを作る

[git commit log](https://github.com/fukmaru/wiki/commit/cd30afcad46bd6c92d9c25a1bb32470b4c88958b)

##### まずは、Rails newでアプリを作りましょう。

```hash
rails new wiki --database=postgresql --skip-coffee --skip-turbolinks --skip-sprockets --webpack
```

:coffee:
Rails new オプションについて [参考 - railsdocs](http://railsdoc.com/rails)

|オプション|説明|
|:---|:---|
| -d, --database=DATABASE | データベースの種類をしていします。今回は、PGを利用します。デフォルトはsqlite3 |
| --skip-coffee | CoffeeScriptsを使いたくない |
| --skip-turbolinks | turbolinksを使いたくない （Vueを後に使いたいので） |
| --skip-sprockets | webpackを使うので、Asset Piplineは使いません |

プロジェクトファイルに移動します

```bash
$ cd wiki
```

### Railsサーバーを起動してみる

foreman を使って、サーバープロセスを整理しようと思います。
foreman については、この記事がとっても参考になります！！
<https://qiita.com/7kaji/items/6a59977d2ad85604e7fd>

ローカル開発用のProcfileを作ります。ローカル開発環境と、Heroku環境とかで分けるときなんかに便利ですね。

```bash
$ touch Procfile.dev
```

```text:./Procfile.dev
web: bin/rails server
```

##### Railsサーバーの起動

```
$ foreman start -f Procfile.dev
09:44:27 web.1  | started with pid 1290
09:44:28 web.1  | => Booting Puma
09:44:28 web.1  | => Rails 5.2.3 application starting in development
09:44:28 web.1  | => Run `rails server -h` for more startup options
09:44:30 web.1  | Puma starting in single mode...
09:44:30 web.1  | * Version 3.12.1 (ruby 2.5.1-p57), codename: Llamas in Pajamas
09:44:30 web.1  | * Min threads: 5, max threads: 5
09:44:30 web.1  | * Environment: development
09:44:30 web.1  | * Listening on tcp://localhost:5000
09:44:30 web.1  | Use Ctrl-C to stop
09:44:41 web.1  | Started GET "/" for ::1 at 2019-04-26 09:44:41 +0900
```

:point_up:
`-f` オプションを使用し、ファイルを指定することを忘れずに。
`-f Procfile.dev` のところですね。

<http://localhost:5000/> を開くと、こんな画面が表示されます。

<img width="796" alt="スクリーンショット 2019-04-26 10.00.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263973/157dcfdf-b35d-35d8-e8b2-b09c316a28a0.png">


##### トラブルシュート

`FATAL: database "wiki_development" does not exist` 
というエラー表示が出た場合には、

```bash
$ $ rails db:reset db:migrate
Dropped database 'wiki_development'
Dropped database 'wiki_test'
Created database 'wiki_development'
Created database 'wiki_test'
```

### webpack-dev-server を入れる

webpack-dev-serverを追加します。
w

```bash
yarn add -D webpack-dev-server
```

`./package.json` にて、

```json:./package.json
  ...
  "devDependencies": {
    "webpack-dev-server": "^3.3.1"
  }
  ...
```

となっているのがわかると思います。

一旦 `foreman` を止めて（`Control`+`c`）、 Procfile.dev も編集しておきます。

```text:./Procfile.dev
web: bin/rails server
+ assets: bin/webpack-dev-server
```

この状態で、foreman を起動します。

```bash
$ foreman start -f Procfile.dev
15:20:28 web.1    | started with pid 23904
15:20:28 assets.1 | started with pid 23905
15:20:29 web.1    | => Booting Puma
15:20:29 web.1    | => Rails 5.2.3 application starting in development
15:20:29 web.1    | => Run `rails server -h` for more startup options
15:20:30 assets.1 | ℹ ｢wds｣: Project is running at http://localhost:3035/
15:20:30 assets.1 | ℹ ｢wds｣: webpack output is served from /packs/
15:20:30 assets.1 | ℹ ｢wds｣: Content not from webpack is served from /Users/fukushi/Development/wiki/public/packs
15:20:30 assets.1 | ℹ ｢wds｣: 404s will fallback to /index.html
15:20:32 assets.1 | ℹ ｢wdm｣: Hash: 085fa9a799e4f598d77b
15:20:32 assets.1 | Version: webpack 4.30.0
15:20:32 assets.1 | Time: 1265ms
15:20:32 assets.1 | Built at: 2019/04/22 15:20:32
15:20:32 assets.1 |                                      Asset       Size       Chunks             Chunk Names
15:20:32 assets.1 |     js/application-3e475f530249b98dde5a.js    376 KiB  application  [emitted]  application
15:20:32 assets.1 | js/application-3e475f530249b98dde5a.js.map    426 KiB  application  [emitted]  application
15:20:32 assets.1 |                              manifest.json  364 bytes               [emitted]
15:20:32 assets.1 | ℹ ｢wdm｣: Compiled successfully.
15:20:32 web.1    | Puma starting in single mode...
15:20:32 web.1    | * Version 3.12.1 (ruby 2.5.1-p57), codename: Llamas in Pajamas
15:20:32 web.1    | * Min threads: 5, max threads: 5
15:20:32 web.1    | * Environment: development
15:20:32 web.1    | * Listening on tcp://localhost:5000
15:20:32 web.1    | Use Ctrl-C to stop
```

##### webpack周りのファイルを`app/javascript/*`から、`frontend`ディレクトリに移動させて管理しやすくします

以下のサイトを参考にwebpack周りのファイル整理していこうと思います。
<https://evilmartians.com/chronicles/evil-front-part-1> 
和訳：<https://techracho.bpsinc.jp/hachi8833/2017_12_26/49931>

`js`, `css`, `images`, 等は、webpack側で管理するので、`app/assets` を消しちゃいます。

```bash
$ rm -rf app/assets
```

:coffee:
`rm` コマンドの `rf` オプションは、ファイル・ディレクトリを削除対象にします。[参考](https://eng-entrance.com/linux_command_rm#-r--recursive)

次に、webpackerで管理されるファイルも `./app/javascript` から、 `./frontend` に移動します。 さらにコンポーネントを設定していきましょう。

```bash
$ mv app/javascript frontend
$ mkdir frontend/init
$ touch frontend/init/index.js
$ touch frontend/init/index.css
```

```js:./frontend/packs/application.js
import "init";
```

```js:./frontend/init/index.js
import "./index.css";
```

```css:./frontend/init/index.css
body {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 16px;
  line-height: 24px;
}
```

[normalize.css](https://necolas.github.io/normalize.css/) を使いたいので、yarnで追加して、`./frontend/init/index.css`で読み込みます。

```bash
yarn add normalize.css
```

```css:./frontend/init/index.css
+ @import "normalize.css/normalize.css";

body {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 16px;
  line-height: 24px;
}
```

#### webpacker.ymlで、webpackerの読み込みフォルダを指定します

```yml:./config/webpacker.yml
default: &default
-  source_path: app/javascript
+  source_path: frontend
  source_entry_path: packs
  public_root_path: public
```

ERBファイルをfrontend配下に置きたいので、application_controller.rbでテンプレートで見つけられるようにします。[参考](https://qiita.com/ngtk/items/cd406961cf62531a81c5)

```rb:./app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
+  prepend_view_path Rails.root.join("frontend")
end
```

#### pack_tag を使うように変更する

```erb:./app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>Wiki</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

-    <%= stylesheet_link_tag    'application', media: 'all' %>
+    <%= stylesheet_pack_tag 'application' %>    
-    <%= javascript_include_tag 'application' %>
  </head>

  <body>
    <%= yield %>
+    <%= javascript_pack_tag "application" %>
  </body>
</html>

```

Asset Pipelineへのいくつかの課題解決（特にバンドルインストール周り）に共感したので、今回はこの方式を採用します。簡単なアプリなので、それほど大きなプロジェクトになりませんが、Reactなどいろいろ追加していきたいので、ご参考程度に。。。

[git commit log](https://github.com/fukmaru/wiki/commit/cd30afcad46bd6c92d9c25a1bb32470b4c88958b)

# トップページを作ります

[git commit log](https://github.com/fukmaru/wiki/commit/ede4d9a4f0f10378ff37ce4f4c0396c7d3a8e529)

```bash
$ rails g controller pages home --skip-test-framework --skip-assets --skip-helper
$ mkdir -p frontend/components/page
$ touch frontend/components/page/{_page.html.erb,page.css,page.js}
```

:coffee:
rails generate(g) のskipオプションに関しては、こんな感じです。

| option | 説明 |
|:--|:--|
| --skip-test-framework | テストの作成をスキップ |
| --skip-assets | assetsの作成をスキップ |
| --skip-helper | helperの作成をスキップ |

:coffee:
ちなみに、 `touch` コマンドで、`{` `}` で囲むと、連番とかのファイルを１コマンドで作成できます。
参考: [連番ファイルをコマンド一発で作成する](https://kazmax.zpp.jp/linux/bash_tips.html)

```rb:./config/routes.rb
Rails.application.routes.draw do
-   get 'pages/home'
+   root to: "pages#home"
end
```

```js:./frontend/components/page/page.js
import "./page.css";
```

```css:./frontend/components/page/page.css
.page {
    background-color: blue;
    color: white;
}
```

```erb:./frontend/components/page/_page.html.erb
<div class="page">
  <%= yield %>
</div>
```

```erb:./app/views/pages/home.html.erb
<%= render "components/page/page" do %>
  <p>Wiki Top Page</p>
<% end %>
```

```js:frontend/packs/application.js
import "init";
+ import "components/page/page"
```

##### 画面を見てみよう

```bash
foreman start -f Procfile.dev
```

こんな感じの画面が表示されていれば全てうまくいってます:ok_hand:

<img width="796" alt="スクリーンショット 2019-04-26 10.56.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263973/a561d2c0-b721-04af-b2c7-c10de4c9b6c4.png">

`page` classにCSSがあたってるのもわかると思います。

[git commit log](https://github.com/fukmaru/wiki/commit/ede4d9a4f0f10378ff37ce4f4c0396c7d3a8e529)


### [Next!](https://qiita.com/fukmaru/items/cd9c1c9c8658ac4a0a89)

CSSフレームワークの[Bulma](https://bulma.io/)を導入してみたいと思います。