LoginSignup
25
27

More than 5 years have passed since last update.

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

Posted at

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

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

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

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

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

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

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

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

lib/templates/migration/templates/create_table_migration.rb

25
27
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
27