AB Lab

abgata20000 blog.

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

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

RailsのScaffoldを使う際にテンプレートをslimで、

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

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

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

config/application.rb

1
2
3
config.generators do |g|
  g.template_engine :slim
end

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

img

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

参考サイト: rails g scaffold のカスタマイズ

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

1
rake rails:templates:copy

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

lib/template/scaffold 作成して、

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

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

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

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

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

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

1
rails g generator slim/scaffold

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

生成されたフォルダ内の

scaffold_generator.rb

を編集します。

scaffold_generator.rb
1
2
3
4
5
6
7
8
9
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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')

こんな感じですね。

ちょっとハマったのは、

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

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

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

1
2
3
4
5
6
tbody
  - @<%= plural_table_name %>.each do |<%= singular_table_name %>|
    tr
      <% attributes.reject(&:password_digest?).each do |attribute| -%>
      td= <%= singular_table_name %>.<%= attribute.name %>
      <% end -%>

のように記述すると

1
2
tr
    td

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

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

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

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

1
rake rails:templates:copy

で生成されていました。

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

サンプルは、

ruby:model.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<% 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 -%>

こんな感じです。

1
rails g scaffold sample name comment:text

img

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

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

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

lib/templates/migration/templates/create_table_migration.rb

Comments