Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした