RailsのScaffoldのテンプレートをカスタマイズする

##Scaffoldで生成されるテンプレートをSlimに変更する

Railsの__Scaffold__を使う際にテンプレートを__slim__で、

生成してさらに中身をカスタマイズできるようにしたくなったのでいろいろ調べてみました。


テンプレートエンジンを__slim__に変更するのは、簡単そうです。


Gemfileに `gem 'slim-rails'` を追加して `bundle install` を実行して、


`config/application.rb`に


```
config.generators do |g|
  g.template_engine :slim
end
```

を追加するだけで出来ました。


![img](https://abgata.s3-ap-northeast-1.amazonaws.com/6447d37569b96333c8981ebcab978d70.png)


##さらに、これの中身をカスタマイズしたい


参考サイト: [rails g scaffold のカスタマイズ](http://qiita.com/labocho/items/387e7592b8e388fd9ca5)

現在利用しているテンプレートのコピーを作成します

```
rake rails:templates:copy
```


これで `lib/templates` が生成されます


`lib/template/scaffold` 作成して、

`index.html.erb` などのテンプレートファイルを作成すれば

`rails g scaffold` 時に反映されるようです。


###テンプレートのカスタマイズもSlimで書きたい

デフォルトでは、テンプレートエンジンは `erb` になっています。


このままでも良かったのですが、折角なので、

テンプレートのカスタマイズも__slim__で出来るようにしました。

```
rails g generator slim/scaffold
```


で、`lib/generators/slim/scaffold` が生成されます。


生成されたフォルダ内の

`scaffold_generator.rb`

を編集します。

#####scaffold_generator.rb
```
require "rails/generators/erb/scaffold/scaffold_generator"
class Slim::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
  source_root File.expand_path('../templates', __FILE__)

  protected
  def handler
    :slim
  end
end
```


これで、scaffold時に `lib/generators/slim/scaffold/template` 内のファイルが利用されるようになります。

#####index.html.slim
```
h1
  | <%= plural_table_name %>

table class=("table table-boderd table-striped table-hover")
  thead
    tr
<% attributes.reject(&:password_digest?).each do |attribute| -%>
      th <%= attribute.human_name %>
<% end -%>
      th
      th
      th

  tbody
    - @<%= plural_table_name %>.each do |<%= singular_table_name %>|
      tr
<% attributes.reject(&:password_digest?).each do |attribute| -%>
        td= <%= singular_table_name %>.<%= attribute.name %>
<% end -%>
        td= link_to 'Show', <%= singular_table_name %>, :class => 'btn btn-info'
        td= link_to 'Edit', edit_<%= singular_table_name %>_path(<%= singular_table_name %>), :class => 'btn btn-success'
        td
          = link_to('Destroy',
            <%= singular_table_name %>,
            method: :delete,
            :remote => true,
            :onclick => 'if(window.confirm("are you sure?")){$(this).closest("tr").fadeOut()}',
            data: {},
            :class => 'btn btn-danger')

```

こんな感じですね。

ちょっとハマったのは、

```
<% attributes.reject(&:password_digest?).each do |attribute| -%>
      th <%= attribute.human_name %>
<% end -%>
```

のようなscaffold時に生成される箇所にインデントがあると、

生成されたslimファイルのインデントがおかしくなるという点です。


```
tbody
  - @<%= plural_table_name %>.each do |<%= singular_table_name %>|
    tr
      <% attributes.reject(&:password_digest?).each do |attribute| -%>
      td= <%= singular_table_name %>.<%= attribute.name %>
      <% end -%>

```

のように記述すると

```
tr
    td

```

とインデントが余分に入ってしまいました。



##折角なのでcontrollerとmodelもカスタマイズする


controllerは、`lib/templates/rails/scaffold_controller/controller.rb`を編集すればいいようです。

このファイルは、最初に実行した

```
rake rails:templates:copy
```

で生成されていました。


modelは、`lib/templates/active_record/model/model.rb`を作成する必要があります。


サンプルは、

#####ruby:model.rb
```
<% module_namespacing do -%>
class <%= class_name %> < <%= parent_class_name.classify %>
<% attributes.select {|attr| attr.reference? }.each do |attribute| -%>
  belongs_to :<%= attribute.name %><%= ', polymorphic: true' if attribute.polymorphic? %>
<% end -%>
<% if !accessible_attributes.empty? -%>
  # attr_accessible <%= accessible_attributes.map {|a| ":#{a.name}" }.sort.join(', ') %>
<% else -%>
  # attr_accessible :title, :body # rails4 だとエラー出ます
<% end -%>


  def to_s
    <%- if attributes.map{ |a| a.name }.include?('name') -%>
    name
    <%- else -%>
    "<%= class_name %> #{id}"
    <%- end -%>
  end

end
<% end -%>


```


こんな感じです。


```
rails g scaffold sample name comment:text
```

![img](https://abgata.s3-ap-northeast-1.amazonaws.com/44c06e14945c626cc741f6a04dac0314.png)


で生成されるファイルが変更されたのを確認できます。


さて、どんなテンプレートにしようかな。



##migrationのテンプレートカスタマイズ

`lib/templates/migration/templates/create_table_migration.rb`