オレオレscaffold generator を作る
Ruby on Rails の Scaffold generator はアプリの元になるコードを生成するに便利ですが実際のアプリを作る際には、XMLをレスポンスするコードは要らないとか、日本語じゃないとか、テンプレートがイマイチだとかいろいろ不満点があると思います。 標準のScaffoldの作成するコードを少し変えるだけならとても簡単です。
オレオレscaffold generatorを置く場所
まず、オレオレscaffold generator を置く場所ですが、Ruby on Rails guidesの 2.3 The Rails Generation: Generatorsにあるように RAILS_ROOT/lib/generators 、 ~/.rails/generators などが考えられます。プロジェクト固有のオレオレscaffoldなら RAILS_ROOT/lib/generatorsが良いかもしれませんが、今回は オレオレ ということで ~/.rails/generators に作ってみます。
標準のScaffoldをコピー
Scaffold generatorはgeneratorのコードと生成するコードのテンプレートから出来ています。今回はgeneratorはScaffoldをそのまま使うので、 ScaffoldGeneratorクラスを継承するだけです。テンプレートは Scaffoldのものをコピーし自分用に変更します。
% mkdir ~/.rails/generators/my_scaffold % cd ~/.rails/generators/my_scaffold % cp -r /opt/local/lib/ruby/gems/1.8/gems/rails-2.3.2/lib/rails_generator/generators/components/scaffold/templates . # ↑ gem のパスは自分の環境に合わせて変えて下さい % cat > my_scaffold_generator.rb class MyScaffoldGenerator < ScaffoldGenerator end ^D % % vi templates/controller.rb % vi templates/view_index.html.erb .... %
使ってみる
% rails test % cd test % ./script/generate --help Usage: script/generate generator [options] [args] Rails Info: -v, --version Show the Rails version number and quit. ... Installed Generators User: my_scaffold ← オレオレscaffold generatorがあります !! Rubygems: gruff, i18n, i18n_locale, i18n_scaffold, i18n_translation, rspec, rspec_controller, rspec_model, rspec_scaffold, web_service Builtin: controller, helper, integration_test, mailer, metal, migration, model, observer, performance_test, plugin, resource, scaffold, session_migration .... % ./script/generate my_scaffold todo due:date task:string ← 使って試してみる
とても簡単です (^_^)
私の作った オレオレテンプレート
- controller.rb
# <%= class_name %>コントロラー class <%= controller_class_name %>Controller < ApplicationController # 一覧 def index @<%= table_name %> = <%= class_name %>.all end # 詳細表示 def show @<%= file_name %> = <%= class_name %>.find(params[:id]) end # 新規作成画面 def new @<%= file_name %> = <%= class_name %>.new end # 編集画面表示 def edit @<%= file_name %> = <%= class_name %>.find(params[:id]) end # 新規作成処理 def create @<%= file_name %> = <%= class_name %>.new(params[:<%= file_name %>]) if @<%= file_name %>.save flash[:notice] = '<%= class_name %> を作成しました。' redirect_to(@<%= file_name %>) else render :action => "new" end end # 編集処理 def update @<%= file_name %> = <%= class_name %>.find(params[:id]) if @<%= file_name %>.update_attributes(params[:<%= file_name %>]) flash[:notice] = '<%= class_name %> を更新しました。' redirect_to(@<%= file_name %>) else render :action => "edit" end end # 削除 def destroy @<%= file_name %> = <%= class_name %>.find(params[:id]) @<%= file_name %>.destroy redirect_to(<%= table_name %>_url) end end
- view_index.html.erb
<h1><%= plural_name %>一覧</h1> <table> <tr> <% for attribute in attributes -%> <th></th> <th><%= attribute.column.human_name %></th> <% end -%> </tr> <%% @<%= plural_name %>.each do |<%= singular_name %>| %> <tr> <td> <%%= link_to '表示', <%= singular_name %> %> <%%= link_to '編集', edit_<%= singular_name %>_path(<%= singular_name %>) %> <%%= link_to '削除', <%= singular_name %>, :confirm => '削除してよいですか?', :method => :delete %> </td> <% for attribute in attributes -%> <td><%%=h <%= singular_name %>.<%= attribute.name %> %></td> <% end -%> </tr> <%% end %> </table> <br /> <%%= link_to '新規作成', new_<%= singular_name %>_path %>
- view_show.html.erb
<h1><%= singular_name %> 詳細</h1> <div class="detail"> <dl> <% for attribute in attributes -%> <dt><%= attribute.column.human_name %>:</dt> <dd><%%=h @<%= singular_name %>.<%= attribute.name %> %></dd> <% end -%> </dl> </div> <%%= link_to '戻る', <%= plural_name %>_path %>
- view_edit.html.erb (view_new.html.erbもほぼ同じ)
<h1><%= singular_name %> 編集</h1> <div class="entry"> <%% form_for(@<%= singular_name %>) do |f| %> <%%= f.error_messages %> <dl> <% for attribute in attributes -%> <dt><%%= f.label :<%= attribute.name %> %></dt> <dd><%%= f.<%= attribute.field_type %> :<%= attribute.name %> %></dd> <% end -%> </dl> <div class="op_buttons"> <%%= f.submit '更新' %> </div> <%% end %> </div> <%%= link_to '戻る', <%= plural_name %>_path %>
- style.css の追加分
div.detail, div.entry { } div.detail dt, div.entry dt { float: left; width: 5em; padding: 2px 0px 2px 10px; } div.detail dd, div.entry dd { margin-left: 5em; padding: 2px 0px 2px 20px; }