Scaffoldでslimのカスタマイズをしてみた

#これはなに
##概要
railsのscaffoldをカスタマイズする時に、slimでの出力に苦戦したので、それを実現するまでの奮闘記
##こんな人向け
・railsのテンプレートエンジンをslimにしている人
　またはrailsのテンプレートエンジンをslimにしたいと思っている人
・scaffoldのカスタマイズをしているが、viewのカスタマイズを諦めている人
　またはscaffoldのカスタマイズをしたい人
##環境
`Rails 6.0.2.2`
`ruby 2.6.5`

#実装までの事前準備
##その１　テンプレートエンジンをslimにする
こちらの記事を参考にして、`slim-rails`というgemを追加します。
https://qiita.com/ftyabu/items/42eb62901b6b56a7dc72

##その２　scaffoldのテンプレートをカスタマイズできるようにする
こちらの記事を参考にして、テンプレートの作成と、その参照先を変更します。
https://qiita.com/akito1986/items/d9f379191fd6b98de955

#実現までの手順
##その１　ディレクトリ名をerbからslimに変更
上記の「その２」で以下のようなファイルが作成されていると思います。
(設定によって違いがあるかも)


 ``` terminal
$ tree lib/templates
lib/templates
├── erb
│   ├── controller
│   │   ├── templates
│   │   │   └── view.html.erb
│   │   └── view.html.erb
│   ├── mailer
│   │   ├── templates
│   │   │   ├── view.html.erb
│   │   │   └── view.text.erb
│   │   ├── view.html.erb
│   │   └── view.text.erb
│   └── scaffold
│       ├── _form.html.erb
│       ├── edit.html.erb
│       ├── index.html.erb
│       ├── new.html.erb
│       ├── show.html.erb
│       └── templates
│           ├── _form.html.erb
│           ├── edit.html.erb
│           ├── index.html.erb
│           ├── new.html.erb
│           └── show.html.erb
└── rails
    ├── assets
    │   ├── javascript.js
    │   ├── stylesheet.css
    │   └── templates
    │       ├── javascript.js
    │       └── stylesheet.css
    ├── controller
    │   ├── controller.rb
    │   └── templates
    │       └── controller.rb
    ├── helper
    │   ├── helper.rb
    │   └── templates
    │       └── helper.rb
    └── scaffold_controller
        ├── api_controller.rb
        ├── controller.rb
        └── templates
            ├── api_controller.rb
            └── controller.rb

16 directories, 28 files
```
この「erb」ディレクトリを「slim」に変更しましょう。
##その２　ファイルをerb.tt仕様からslim.tt仕様に書き換える
さて、ここからが本番です。
参考になる記事を探したものの、なかなか見つかりませんでした。
まずは対象ファイルの中身をみてみましょう

lib/templates/erb/scaffold/index.html.erb.tt

```
<p id="notice"><%%= notice %></p>

<h1><%= plural_table_name.titleize %></h1>

<table>
  <thead>
    <tr>
<% attributes.reject(&:password_digest?).each do |attribute| -%>
      <th><%= attribute.human_name %></th>
<% end -%>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <%% @<%= plural_table_name %>.each do |<%= singular_table_name %>| %>
      <tr>
<% attributes.reject(&:password_digest?).each do |attribute| -%>
        <td><%%= <%= singular_table_name %>.<%= attribute.column_name %> %></td>
<% end -%>
        <td><%%= link_to 'Show', <%= model_resource_name %> %></td>
        <td><%%= link_to 'Edit', edit_<%= singular_route_name %>_path(<%= singular_table_name %>) %></td>
        <td><%%= link_to 'Destroy', <%= model_resource_name %>, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <%% end %>
  </tbody>
</table>

<br>

<%%= link_to 'New <%= singular_table_name.titleize %>', new_<%= singular_route_name %>_path %>

```

erbを普段から使う人にとっては馴染みのあるんでしょうか、`<%%=`の記号は良くわかりませんでした。

https://qiita.com/ykhirao/items/7ff9ce515a82a6dd24ea
こちらの記事に`<%%=`のことが紹介されていました。erbを一度展開しても、erbファイルが壊れないようにするためなんですね。

slimでそれを実現するにはどうしたらいいんだろう。。

##その3　(失敗)とりあえずgemにぶち込んでみればなんとかなる説の立証
ここでふと思い出しました。`erb2slim`の存在を。

「erbは正しく書かれているし、直してくれるだろう」と信じ、試してみましたが。。

lib/templates/erb/scaffold/index.html.slim

```
p#notice
  - %= notice
h1
  = plural_table_name.titleize
table
  thead
    tr
      - attributes.reject(&:password_digest?).each do |attribute|
        th
          = attribute.human_name
      th[colspan="3"]
  tbody
    |  <ruby code="% @
    = plural_table_name
    | .each do |
    = singular_table_name
    | | "> 
    tr
      - attributes.reject(&:password_digest?).each do |attribute|
        td
          - %= <%= singular_table_name
          | .
          = attribute.column_name
          |  %>
      td
        - %= link_to 'Show', <%= model_resource_name
        |  %>
      td
        - %= link_to 'Edit', edit_<%= singular_route_name
        | _path(
        = singular_table_name
        | ) %>
      td
        - %= link_to 'Destroy', <%= model_resource_name
        | , method: :delete, data: { confirm: 'Are you sure?' } %>
    - % end
br
- %= link_to 'New <%= singular_table_name.titleize
| ', new_
= singular_route_name
| _path %> 

```
崩壊のにおいしかしない。。。笑
案の定scaffoldを実行するとsyntaxエラーの連発でした。
やはり自力で修正する方が確実そう

##その４　slim-railsからヒントを得る
とはいえ、何かしたのとっかかりが欲しいなと思って、いろいろと調べていると、ふと
「そもそもslim-railsはscaffoldのテンプレートをいじってるはず」
と我ながら筋の良い勘が働いたので、確認してみました。すると、、、
https://github.com/slim-template/slim-rails
ありました。

slim-rails/lib/generators/slim/scaffold/templates/index.html.slim

```
h1 Listing <%= plural_table_name %>

table
  thead
    tr
<% attributes.each do |attribute| -%>
      th <%= attribute.human_name %>
<% end -%>
      th
      th
      th

  tbody
    - @<%= plural_table_name %>.each do |<%= singular_table_name %>|
      tr
<% attributes.each do |attribute| -%>
        td = <%= singular_table_name %>.<%= attribute.name %>
<% end -%>
        td = link_to 'Show', <%= singular_table_name %>
        td = link_to 'Edit', edit_<%= singular_table_name %>_path(<%= singular_table_name %>)
        td = link_to 'Destroy', <%= singular_table_name %>, data: { confirm: 'Are you sure?' }, method: :delete

br

= link_to 'New <%= human_name %>', new_<%= singular_table_name %>_path

```
つまりこれを参考にして、自分好みにテンプレートを変更すればいいんですね。
見つけてしまえばこちらのもの。文言を変えたり、構造を変えたり、こまめに実験しながら、素敵なカスタマイズ生活をお送りください。

#結論
困ったらソースコード
早期に気づけてたら一瞬で解決していた