CodeZine(コードジン)

特集ページ一覧

Ruby on Rails + Curl
Curl用Scaffoldを自作する

第3回

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加
2009/07/21 15:00

ダウンロード サンプルソース (5.4 KB)

目次

Ruby on RailsのScaffoldの仕組み

 Scaffoldをはじめ、Ruby on Railsに組み込まれているコードジェネレータについて詳しく書かれた日本語の情報は少ないです。英語のドキュメントとしてはAPIドキュメントのModule Rails::Generatorが参考になりますが、やはりRuby on Railsのソースコードを読むのが一番分かりやすいです。

 ScaffoldジェネレータのソースはRubyがC:¥Rrubyにインストールされている場合、C:¥Ruby¥lib¥ruby¥gems¥1.8¥gems¥rails-2.3.2¥lib¥rails_generator¥generators¥components¥scaffold¥scaffold_generator.rbになります。このファイルと同じディレクトリにあるtemplatesディレクトリの下に、生成するコードの元になるファイルが置かれています。

テンプレート

 templatesディレクトリにあるview_show.html.erbを見てみましょう

<% for attribute in attributes -%>
<p>
  <b><%= attribute.column.human_name %>:</b>
  <%%=h @<%= singular_name %>.<%= attribute.name %> %>
</p>

<% end -%>

<%%= link_to 'Edit', edit_<%= singular_name %>_path(@<%= singular_name %>) %> |
<%%= link_to 'Back', <%= plural_name %>_path %>

 これは詳細表示用のテンプレートで第1回の例ではapp/views/players/show.html.erbファイルがこのテンプレートから作られています。app/views/players/show.html.erbの一部を見てみましょう。

<p>
  <b>Name:</b>
  <%=h @player.name %>
</p>

<p>
  <b>Team:</b>
  <%=h @player.team %>
</p>

  ・・・ 省略 ・・・
  
<b>Assist:</b>
  <%=h @player.assist %>
</p>

<%= link_to 'Edit', edit_player_path(@player) %> |
<%= link_to 'Back', players_path %>

 view_show.html.erb内の<%% ~ %>タグはそのまま<% ~ %>タグに置き換わっています。ただし<% ~ %>の内容が評価されてテンプレートを展開しています。またplural_name、singular_name、attributesなどの変数が使われているのが分かります。

Scaffoldジェネレータ

 Scaffoldジェネレータ本体scaffold_generator.rbを上から見てみましょう。ScaffoldGeneratorクラスは、ジェネレータの元になるRails::Generator::NamedBaseクラスを継承しています。また、ジェネレータで使われるコントローラ名、そのファイル名などの属性(インスタンス変数)が定義されています。

class ScaffoldGenerator < Rails::Generator::NamedBase
  default_options :skip_timestamps => false, :skip_migration => false, :force_plural => false

  attr_reader   :controller_name,
                :controller_class_path,
                :controller_file_path,
 ・・・ 省略 ・・・

 初期化メソッドinitializeでは、ジェネレータで使われるコントローラ名、そのファイル名などの設定が行われます。

def initialize(runtime_args, runtime_options = {})
  super

  if @name == @name.pluralize && !options[:force_plural]
    logger.warning "Plural version of the model detected, using singularized version.  Override with --force-plural."
    @name = @name.singularize
  end

  @controller_name = @name.pluralize

  base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
 ・・・ 省略 ・・・
end

 manifestメソッドがジェネレータのメインです。ここでは、m.class_collisions()でこれから作成するファイルがダブらないかチェックし、m.directory()で必要なディレクトリーを作成し、m.template()でテンプレートを元に必要なファイルを作成しています。

 また、m.route_resourcesのようにconfig/route.rbを変更する専用のメソッドなどもあります。さらに、Scaffoldではモデルの作成部分はm.dependency 'model'……でmodelジェネレータを呼び出しています。

def manifest
  record do |m|
    # Check for class naming collisions.
    m.class_collisions("#{controller_class_name}Controller", "#{controller_class_name}Helper")
    m.class_collisions(class_name)

    # Controller, helper, views, test and stylesheets directories.
    m.directory(File.join('app/models', class_path))
    m.directory(File.join('app/controllers', controller_class_path))
    m.directory(File.join('app/helpers', controller_class_path))
 ・・・ 省略 ・・・

    for action in scaffold_views
      m.template(
        "view_#{action}.html.erb",
        File.join('app/views', controller_class_path, controller_file_name, "#{action}.html.erb")
      )
    end

    # Layout and stylesheet.
    m.template('layout.html.erb', File.join('app/views/layouts', controller_class_path, "#{controller_file_name}.html.erb"))
    m.template('style.css', 'public/stylesheets/scaffold.css')

    m.template(
      'controller.rb', File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb")
    )

 ・・・ 省略 ・・・

    m.route_resources controller_file_name

    m.dependency 'model', [name] + @args, :collision => :skip
  end
end

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • 吉田裕美(ヨシダユウミ)

    有限会社 EY-Office 取締役 CADのベンチャー企業でCADのコア部分や図面管理システムなどの開発に従事した後、独立しJava,Ruby,PerlでWebアプリを中心に開発してきた。現在は殆どの開発はRuby on Rails。 ここ数年はソフトウェアエンジニアの教育に興味をもち、従来の...

バックナンバー

連載:Ruby on Rails + Curl
All contents copyright © 2005-2020 Shoeisha Co., Ltd. All rights reserved. ver.1.5