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
を追加するだけで出来ました。
さらに、これの中身をカスタマイズしたい
参考サイト: 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 -%>
のように記述すると
とインデントが余分に入ってしまいました。
折角なので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
で生成されるファイルが変更されたのを確認できます。
さて、どんなテンプレートにしようかな。
migrationのテンプレートカスタマイズ
lib/templates/migration/templates/create_table_migration.rb