IBM®
本文へジャンプ
    Japan [変更]    ご利用条件
 
 
検索範囲検索:    
    ホーム    製品    サービス & ソリューション    サポート & ダウンロード    マイアカウント    
skip to main content

developerWorks Japan  >  Linux | Open source | Web development  >

ActiveScaffold を使って Ruby on Rails を機能アップする

RoR から単調な作業を除く: データ入力ページの処理を ActiveScaffold に任せる

developerWorks
ページオプション

JavaScript を要するドキュメントオプションは表示されません

サンプルコード

原文はこちら

原文はこちら


レベル: 中級

Mike Perham (developerworks@perham.net), Senior Software Engineer, IBM

2007年 6月 08日

Ruby on Rails の ActiveScaffold プラグインを使うことで、時間を節約して、頭痛の種を解消し、もっと管理のしやすいページを作成しましょう。ActiveScaffold はユーザー・インターフェースの CRUD (create, read, update, delete) に必要なことをすべて処理してくれるため、開発者はより多くの時間を、難しい (そして興味深い) 問題に集中して費やせるようになります。

複雑なアプリケーションの Web ベースのデータ入力用 UI を作成する作業は楽しいものではなく、相当退屈なことが多いものです。優れたユーザー・インターフェースの重要な特性である一貫性を持った Web ページを作成するには、知識が豊富で勤勉な開発チームが、最初から最後まで設計に従った作業をする必要があります。Ruby on Rails も、他のすべての Web アプリケーション・フレームワークと同様、この同じ問題を抱えています。しかし Ruby 言語の動的な性質のおかげで、ActiveScaffold というソリューションを利用することができます。ActiveScaffold は Ruby on Rails (Rails としても知られています) のプラグインであり、動的なモデルをベースにしたビューを生成します。ActiveScaffold では、モデルを表示するためのページを手動で作成する必要はなく、ActiveScaffold が ActiveRecord モデルのイントロスペクションを行い、これらのモデルのオブジェクトを処理するための CRUD (create, read, update, delete) ユーザー・インターフェースを動的に生成します。

この記事は、(この記事の執筆時点での) 最新バージョンの ActiveScaffold と Ruby、そして Rails に基づいています (リンクとバージョン番号については「参考文献」を参照してください)。またこの記事は、Ruby on Rails に慣れていること、そしてLinux® あるいは Mac OS X を使うことを前提としています。Windows® ユーザーは、ご自分の環境に合わせてコマンドを変更する必要があります (例えばスクリプト・コマンドの最初に 'ruby' を追加する、など)。

ActiveScaffold をインストールする

ActiveScaffold は Rails のプラグインなので、リモートの Web サーバーあるいは Subversion サーバーからインストールすることができます。下記のコマンドを実行すると、ActiveScaffold Subversion サーバーから ActiveScaffold プラグインをチェックアウトします。


リスト 1. ActiveScaffold プラグインをインストールする
                
script/plugin install http://activescaffold.googlecode.com/svn/tags/active_scaffold

このコマンドは、現在のリリース (つまり最新リリース) の ActiveScaffold をチェックアウトすることに注意してください。この記事は 1.0 リリースで動作するように書かれていますが、ActiveScaffold の開発者達は互換性の問題に関して、これまで十分な注意を払ってきているので、おそらく今後のリリースでも動作するはずです。




上に戻る


モデル

最近の Web アプリケーション・フレームワークは MVC (model、view、controller) パターンに基づいているものがほとんどですが、Rails も同じです。Rails のモデルはデータベースに保存されたデータを表現し、データベースの各テーブルには、そのモデルに対応する (Ruby の) ActiveRecord モデル・クラスがあります。この記事では、ユーザーやプロジェクトをたくさん抱える組織のための、単純なプロジェクト追跡アプリケーションを作成します。下記のコードは、このアプリケーションへの ActiveRecord のマイグレーションとそれに対応するモデル・クラスを示しています。これらのモデル・クラスが、Java の世界でのモデル・クラスよりも、はるかに単純なことに注目してください。これは、Rails での DRY (Don't Repeat Yourself) の原則の好例です。マイグレーションには既に列が含まれているため、モデル・クラスの中で再度それらをリストする必要はないのです。


リスト 2. マイグレーション
                
class AddOrganizations < ActiveRecord::Migration
def self.up
create_table :organizations do |t|
t.column :name, :string, :limit => 50, :null => false
end
end

def self.down
drop_table :organizations
end
end

class AddUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.column :first_name, :string, :limit => 50, :null => false
t.column :last_name, :string, :limit => 50, :null => false
t.column :email, :string, :limit => 100, :null => false
t.column :password_hash, :string, :limit => 64, :null => false
t.column :organization_id, :integer, :null => false
end
add_index :users, :email, :unique => true
end

def self.down
drop_table :users
end
end

class AddProjects < ActiveRecord::Migration
def self.up
create_table :projects do |t|
t.column :name, :string, :limit => 50, :null => false
t.column :organization_id, :integer, :null => false
end
end

def self.down
drop_table :projects
end
end

class AddProjectsUsers < ActiveRecord::Migration
def self.up
create_table :projects_users do |t|
t.column :project_id, :integer, :null => false
t.column :user_id, :integer, :null => false
t.column :role_type, :integer, :null => false
end
end

def self.down
drop_table :projects_users
end
end


リスト 3. モデル
                
class User < ActiveRecord::Base
belongs_to :organization
end
class Organization < ActiveRecord::Base
has_many :projects
has_many :users
end
class Project < ActiveRecord::Base
belongs_to :organization
has_many :projects_users
has_many :administrators, :through => :projects_users, :source => :user,
:conditions => "projects_users.role_type = 3"
has_many :managers, :through => :projects_users, :source => :user,
:conditions => "projects_users.role_type = 2"
has_many :workers, :through => :projects_users, :source => :user,
:conditions => "projects_users.role_type = 1"
end
class ProjectsUser < ActiveRecord::Base
belongs_to :project
belongs_to :user
end

プラグインとジェネレーター

Ruby on Rails は 2 種類の「開発アシスタント」をサポートしています。ジェネレーターは静的—であり、1 度だけ実行され、コードを生成します。プラグインは動的—であり、アプリケーション・ランタイムの一部として実行されます。例えば、標準の Rails の scaffold ジェネレーターは 1 度だけ実行され、モデルの中の現在のフィールドに基づいて静的な HTML テンプレートを作成します。列を追加したい場合には、ビューを再生成する (そしてそれまでの変更を失う) か、あるいは手動でビューにフィールドを追加する必要があります。このため、モデルの変更は必要以上に難しくなります。

プラグインは、こうしたビューを実行時に生成します。そのためモデルの変更は、まったく苦労なく行えます。プラグインはジェネレーターと比較して特に欠点はありませんが、ジェネレーターよりも少し使い方が難しいかもしれません。

User テーブルと Organization テーブル、そして Project テーブルは、ユーザーやプロジェクトを抱える組織における従来からのエンティティーを表しますが、ProjectsUsers テーブルは Project と User というエンティティーの間に多対多の関係を追加します。このケースでは、ProjectsUsers テーブルは、プロジェクトにおけるユーザーの役割を表現する role_type プロパティーを追加します。User はワーカーであることもあり、マネージャーであることもあり、管理者であることもあります。

モデルの上にユーザー・インターフェースを作成する際に重要なことは、モデル間の関係を理解することです。モデル群の中で has_manybelongs_to を宣言することによって、モデル間に特定のタイプの関係を定義することになります。ActiveScaffold はこうした関係を認識すると、これらのオブジェクトを操作するためのユーザー・インターフェースを、ユーザーが理解できる形で提供します。このケースでは、ActiveScaffold は Project が Organization によって所有されていると判断し、それに従ってユーザー・インターフェースを調整します。もしこの関係が変更されると、ユーザー・インターフェースはそれに応じて変化するので、開発者は UI を変更する必要がありません。

注釈: 残念ながらリスト 2 のマイグレーションは、Rails のマイグレーション・フレームワークの困った制約のため、外部キーを使っていません。私は、データの一貫性を確保するために外部キーを使うように、強くお勧めします。Redhill Consulting が、Rails のデータベース・マイグレーション・フレームワーク内に外部キーのサポートを追加する、優れた foreign_key_migrations プラグインを提供しています。詳しくは「参考文献」のリンクを参照してください。




上に戻る


Rails の scaffold

モデルが具体化されたので、このモデルをベースに Web インターフェースを作成することができます。Rails には、指定されたモデルに対して基本的な CRUD ページを生成する「scaffold」ジェネレーターが同梱されています。下記のコマンドはモデルに対して、Ruby の標準的な scaffold (つまり一連の CRUD メソッドを持つコントローラーと、それに対応する一連のモデル用 HTML ビュー・セット) を作成します。


リスト 4. Ruby の標準的な scaffold を生成する
                
script/generate scaffold user
script/generate scaffold organization

scaffold ジェネレーターには、次のようないくつかの重要な制限事項があります。

  • 関係のサポートがありません: モデルのインスタンスの作成は、そのインスタンスに対する基本的なプロパティーを単に編集することにすぎません。もしモデルが関係の定義を要求する場合には (例えば Project が、そのプロジェクトを所有する Organization が選択されるように要求する、など)、手動でページを変更し、そのフィールドをフォームに追加する必要があります。

  • 連携動作がありません: 生成されるコードは静的なため、繰り返しのモデル変更をサポートする「連携動作」がありません。従って生成されたコードを変更してしまうと、scaffold を再生成する際にはその変更が失われてしまいます。

  • スタイル設定がありません: 生成されるページは白黒であり、最小限の CSS サポートしかありません。基本的な HTML タグのスタイル設定をしないと、CSS でスキニングをサポートすることができません。

最初の 2 つの項目を合わせて考えると、scaffold は有用なツールというよりも、単なるおもちゃであることがわかります。図 1 は、Rails がデフォルトで提供している scaffold です。


図 1. Rails の標準的な scaffold
Figure 1. The standard Rails scaffolding

Rails には dynamic scaffolding も含まれています。これは基本的に同じコードのサポートを提供しますが、事前にコントローラー・コードを生成する必要がありません。しかし、これによる大きな利点はありません。コードの大部分は HTML ビューの中にあり、相変わらずビュー・コードが要求されます。dynamic scaffolding は、コントローラー・クラスに scaffold メソッドを追加すると有効になります。


リスト 5. Rails の標準的な scaffold を追加する
                
class UsersController < ApplicationController
scaffold :user
end

ご注意ください!
Rails の標準的な scaffold コードは、ActiveScaffold と一緒に使おうとすると問題を起こします。ActiveScaffold に切り替える前に、必ずすべての scaffold コントローラーとビュー・コードを削除する必要があります。




上に戻る


ActiveScaffold のデフォルト表示

ActiveScaffold はモデル用に、非常に便利な UI を提供します。上で説明した、scaffold に関する 3 つの問題は、すべて解決されています。まず、ActiveScaffold scaffold を使うためにコントローラーを変更します。


リスト 6. ActiveScaffold scaffold を追加する
                
class UsersController < ApplicationController
active_scaffold :user
layout "activescaffold"
end

次に、すべての ActiveScaffold ページ用の標準レイアウトを追加します (このコードを app/views/layouts/activescaffold.rhtml に置きます)。


リスト 7. 標準の ActiveScaffold レイアウト
                
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>My Application</title>
<%= javascript_include_tag :defaults %>
<%= active_scaffold_includes %>
</head>
<body>
<%= yield %>
</body>
</html>

これで、ユーザーのリストがもっと見栄えよくなります。


図 2. 標準の ActiveScaffold scaffold
Figure 2. The standard ActiveScaffold scaffolding

速くプロトタイプ化したい場合や開発用には、デフォルトの表示でも十分です。しかしどのデフォルトにも言えるように、少しカスタマイズすると特定の用途に、はるかに適したものになります。




上に戻る


ビューのカスタマイズ

ActiveScaffold はいくつかのフックを持っており、それらを利用するとモデルの表示方法をカスタマイズすることができます。active_scaffold メソッドにオプションの構成ブロックを渡し、その scaffold を構成するために使用することができます。

グローバル構成

ActiveScaffold のグローバル構成を利用すると、すべてのコントローラーにわたってカスタマイズをすることができます。


リスト 8. グローバル構成
                
class ApplicationController < ActionController::Base
AjaxScaffold.set_defaults do |conf|
conf.list.results_per_page = 20
end
end

この例は、レコードをリストする際にページ当たり 20 個の結果を表示するように、システム内のすべての ActiveScaffold scaffold を構成します。

ローカル構成

各 scaffold コントローラーは、それぞれ独自の ActiveScaffold 構成を持つことができます。


リスト 9. 特定のコントローラーに対するローカル構成
                
class UsersController < ApplicationController
active_scaffold :user do |conf|
conf.modules.exclude :update
conf.list.label = 'People'
conf.list.sorting = [{:last_name => :ASC}, {:first_name => :ASC}]
conf.list.columns.exclude :password_hash
end
end

この例は、モデルのインスタンスを更新する機能を削除し、そしてリストのヘッダーを変更し、ユーザー・リストに対するデフォルトのソートをカスタマイズします。sorting によってデータベースからのレコードの返し方をコントロールでき、また sorting は {column => direction} ハッシュの配列を想定します。またここでは、ユーザーが見る必要のない一部の列を、ActiveScaffold が表示しないように構成しました。この例では、password_hash 列は UI で表示しても意味がないので、除外してあります。

ActiveRecord オブジェクトを表示する

to_label メソッドを利用すると、ページ内にモデルのインスタンスを表示する方法をカスタマイズすることができます。ActiveScaffold はデフォルトで、モデルに対して次の一連のメソッドを探します。

  • to_label
  • name
  • label
  • title
  • to_s

最後のメソッドは ActiveRecord によって提供され、"#:<Address:0xFFFFFF:>"として表示されますが、これはあまりユーザー・フレンドリーではありません。下記のメソッドは、これを改善したものです。


リスト 10. モデルの表示をカスタマイズする
                
class User < ActiveRecord::Base
belongs_to :organization

def to_label
first_name << ' ' << last_name
end
end

例えば、あるユーザーの to_labelJohn Doe かもしれません。

プロパティーの表示をカスタマイズする

ActiveScaffold を利用すると、モデルのプロパティーの実際の表示方法を完全にコントロールすることができます。デフォルトでは、ActiveScaffold は単純なプロパティー値に対して to_s を呼び出し、それらを HTML にシリアライズします。これをカスタマイズするためには、単純に列表示ヘルパー・メソッドを、app/helpers/<model>_helper.rb.の対応するヘルパー・クラスに追加します。


リスト 11. プロパティーの表示をカスタマイズする
                
def birthdate_column(record)
record.birthdate.strftime("%d %B %Y")
end

上記のヘルパー・メソッドでは、レコードにフル・アクセスすることができます。この場合、このヘルパーはあまりインテリジェントではなく、ユーザーが要求する、適切な日付フォーマットを判断するためのロケールを理解できません。

ActiveScaffold は、has_manyhas_and_belongs_to_many という関連付けに対して、上で説明した to_label ロジックを使って最初の 3 つのエントリーをレンダリングし、表示します。これらの 3 つのエントリーはリンクされているので、クリックされれば関連付け全体がリストされます。to_label ロジックを使ったおかげで、いきなり大きな関連付けセットが表示されて、ユーザー・インターフェースが埋めつくされてしまうのを防ぐことができます。

フォームの表示

ActiveScaffold は、Rails の ActiveRecord ライブラリーと ActiveView ライブラリーに基づいて、モデルに対するフォームを作成します。varchar 列は、テキスト入力や、HTML のチェックボックスへのブール値によるマップなどになります。

1 つ注意すべきことは、仮想プロパティー (モデルの中では属性として定義されながら、実際にはデータベースに保存されないプロパティー) は、通常のモデル・プロパティーとは異なる HTML レンダリングをすることが可能ということです。名前の中に「パスワード」を含む通常のモデル・プロパティーは、どれもパスワードの入力画面を HTML でレンダリングします。しかし仮想プロパティーでは、そうではありません。これは、仮想プロパティーをパスワード・フォーム入力に使った場合によくわかります。この場合は仮想プロパティーを使ってフォーム入力をキャプチャーし、そして保存の際にキャプチャーした値を password_hash 列にマップします。そのためユーザーが入力したプレーン・テキストは、SHA256 ハッシュとしてデータベースの中に安全に保存されます。


リスト 12. ユーザー・モデルに対して仮想プロパティーを作成する
                
require 'digest/sha2'

class User < ActiveRecord::Base
attr_accessor :password, :password_confirmation
validates_presence_of :password, :password_confirmation

def validate
errors.add('password', 'and confirmation do not match') \
unless password_confirmation == password
end

def before_save
self.password_hash = Digest::SHA256.hexdigest(password) if password
end
end

2 つの form_column ヘルパーを追加し、仮想プロパティーをパスワードの入力画面として正しくレンダリングします。ActiveScaffold は、field_name パラメーターで指定された名前を持つ入力が POST されることを想定します。


リスト 13. 仮想プロパティーのフォーム表示をカスタマイズする
                
def password_form_column(record, field_name)
password_field_tag field_name, record.password
end
def password_confirmation_form_column(record, field_name)
password_field_tag field_name, record.password_confirmation
end




上に戻る


関係 (Relationships)

ここまでは、単純な列の値を表示したり編集したりという、基本的なモデル操作のみを考えました。ActiveScaffold で最も複雑な部分は、モデル同士の関係を判断し、そしてモデルがアプリケーションのユーザー・インターフェースに与える影響を判断する部分です。そうした判断は、ActiveScaffold を何も構成しない状態ではほとんど不可能です。このセクションでは、モデルを適切に処理できるように ActiveScaffold を構成する方法について説明します。

リストの表示

ActiveScaffold はモデルの間をナビゲートするために、リスト・ビューの中に関係リンクを表示します。例えば組織のリストを表示する場合、その Organization の Users を持つページを、Users リンクが表示します。このリンクをカスタマイズするためには、その列に対するヘルパー・メソッドを定義する必要があります。


リスト 14. 関連付けの表示をカスタマイズする
                
def users_column(record)
name = "user"
name = "users" if record.users.size > 1
"<a href="/user/list?user_id=#{record.id}">#{record.users.size} #{name}</a>"
end

フォームの表示

ActiveScaffold は、モデルに定義された関係に基づいて、モデル間のナビゲーションを提供します。例えば belongs_to という関係を取り上げましょう。上記の例では、ある User が Organization に所属 (belongs_to) しています。これはつまり、User が作成される際には、そのユーザーは関連付けられた Organization を持つ必要があるということを意味します (もし Organization がオプションである場合には、代わりに、ヌルが可能の has_one 関係を使います)。ActiveScaffold はこれを理解し、データベースから得られる Organization のリストを <select> の中に表示するため、ユーザーは作成される User に関連付けられた Organization を選ぶことができます。

この方法は、Organization の数が 10 から 20 の程度の小さなデータセットに対しては問題ありませんが、Organization の数が多くなると対応できません。そこで列のレンダリングを、フォーム列レンダラーを使ってオーバーライドすることができます。下記の簡単な例では、どんな値になるかを開発時に知ることができます。


リスト 15. 静的な選択リストを使う
                
def organization_form_column(record, field_name)
# simple example that just hard codes two possible values
select_tag field_name, options_for_select('IBM' => '1', 'Lenovo' => '2')
end




上に戻る


レコードを検索する

ActiveScaffold は、大きなテーブルの中でレコードを発見するために便利な検索機能をいくつか提供しています。scaffold はデフォルトで、リスト・テーブルの上に「Search」リンクを提供します。このリンクはテキスト・ボックスを開き、ユーザーはそこに検索語を入力することができます。ActiveScaffold は、モデルに対するすべての varchar 列を検索する SQL を作成します。そのため、「ham」のような言葉を入力すると、私の姓に基づくユーザー・レコードを見つけます。他の領域と同じく、ここにもいくつかの構成オプションがあります。

ライブ・サーチ

デフォルトの検索は、ユーザーがリターンキーを押下すると動作します。ActiveScaffold は、「live search」を有効にするとリアルタイム検索を行うことができます。これはユーザーの現在の入力に基づいて、毎秒 Ajax コールを行います。ただし、ライブ・サーチはデータベース負荷が重いことに注意してください。以下で説明するように、この機能を使用する前に、検索列を構成したこと、そして適切にテーブルを索引付けしたことを必ず確認します。


リスト 16. デフォルトの検索をライブ・サーチに交換する
                
ActiveScaffold.set_defaults do |conf|
conf.actions.exclude :search
conf.actions.add :live_search
end

ユーザビリティーの調整


リスト 17. scaffold 用に検索構成を調整する
                
active_scaffold :user do |conf|
conf.live_search.columns = [:last_name, :first_name]
conf.live_search.full_text_search = false
end

このコードは ActiveScaffold に対して、この scaffold への検索をユーザーの名前と姓とに制限するように命令し、そしてフル・テキスト検索を無効にしています。後者のオプションは、スケーラビリティーの調整をしており、大きなテーブルの場合に役に立ちます。もしユーザーが「ham」を検索すると、ActiveScaffold はデフォルトでlower(column_name) LIKE "%ham%" のような SQL を生成しますが、これには索引付けすることができません。フル・テキスト検索を無効にすることで、ActiveScaffold に対して、「先頭の何文字かを指定する」検索 (つまり lower(column_name) LIKE "%ham%") を代わりに使うように命令しています。もちろん、これによって検索の柔軟性は制限されますが、スケーラビリティーは非常に高くなります。




上に戻る


カスタム・アクション

ActiveScaffold を利用すると、標準の CRUD アクションの他に、独自のコントローラー・アクションを定義することができます。データベース・アプリケーションでは、PDF や Excel、CSV、あるいは XML でのデータのエクスポートが頻繁に要求されます。この機能の追加は非常に簡単です。まず、対応するアクション・メソッドを持つ「アクション・リンク」をコントローラーに追加します。


リスト 18. カスタム・アクションを定義する
                
class UsersController < ApplicationController
active_scaffold :user do |conf|
conf.action_links.add 'export_csv', :label => 'Export to Excel', :page => true
end

def export_csv
# find_page is how the List module gets its data. see Actions::List#do_list.
records = find_page().items
return if records.size == 0

# Note this code is very generic.  We could move this method and the
# action_link configuration into the ApplicationController and reuse it
# for all our models.
data = ""
cls = records[0].class
data << cls.csv_header << "\r\n"
records.each do |inst|
data << inst.to_csv << "\r\n"
end
send_data data, :type => 'text/csv', :filename => cls.name.pluralize + '.csv'
end
end

実際のモデルのナレッジをモデル自体の中にカプセル化することで、コードをオブジェクト指向のままに保つことができます。


リスト 19. カスタム・アクションに対対応するモデル・メソッド
                
class User < ActiveRecord::Base
...

# The header line lists the attribute names.  ID is quoted to work
# around an issue with Excel and CSV files that start with "ID".
def self.csv_header
""ID",Last Name,First Name,Email,Birthdate"
end

# Emit our attribute values as a line of CSVs
def to_csv
id.to_s << "," << last_name << "," << first_name << "," << email << 
"," << birthdate.to_s
end
end




上に戻る


ローカライズ

ソフトウェアを世界中で使用できるようにするためには、ユーザーの母国語で動作できるということが重要です。Ruby と Rails は、ロケールを処理するための標準 API を提供していません。そのため統合は、例えば Java での場合よりも困難です。ActiveScaffold チームは、単純な参照フック (Object::as_ メソッド) を使うことで、すべてのローカライズをアプリケーションに任せるように決定しました (このメソッドは適当な Ruby ローカライズ・プラグインにフックすることができます)。下記のコードは、メソッド・パラメーターを、Globalize プラグイン (「参考文献」にリンクがあります) が提供する _ メソッド (そうです、このメソッドは実際に「 _ 」という名前なのです) にパススルーする方法を示しています。


リスト 20. ActiveScaffold をローカライズする
                
# Put this at the bottom of your app/controllers/application.rb file
class Object
def as_(string, *args)
# Use Globalize's _ method to provide the actual lookup of the string.
_(string, `	*args)
end
end

Globalize は現在、このメソッドに渡されるすべてのストリングに対して、ローカライズされた翻訳を提供できるようになっています。




上に戻る


ActiveScaffold をスタイリングする

ActiveScaffold は一連のリッチな CSS スタイルを出力し、これを利用すると標準の UI を調整してカスタムのルック・アンド・フィールを提供することができます。オーバーライド用の CSS ファイルを作成し、それを標準の CSS インクルードの後でインクルードすることで、そのサイトでの色やフォント等の使い方に合わてデフォルトのスタイルをオーバーライドすることができます。ここでは、public/stylesheets/as_overrides.css というファイルをインクルードします。


リスト 21. デフォルトの ActiveScaffold のスタイルをオーバーライドする
                
<head>
<title>My Application</title>
<%= javascript_include_tag :defaults %>
<%= active_scaffold_includes %>
<%= stylesheet_include_tag "as_overrides" %>
</head>

標準の ActiveScaffold スタイルシートは、vendor/plugins/active_scaffold/frontends/default/stylesheets/stylesheet.css にあります。




上に戻る


セキュリティー

ActiveScaffold には、データのセキュリティーを保証するための許可 API が提供されています。1 番目のレベルはコントローラーに対する粒度の粗いセキュリティーであり、これは特定のレコードに対するものではありません。コントローラーでは、#{action}_authorized? メソッドを定義することができます (ここで #{action} は、ActiveScaffold のアクション、つまり createlistsearchshowupdate、あるいは delete です)。


リスト 22. コントローラー・ベースのセキュリティー
                
class ProjectsController < ApplicationController
active_scaffold :project do |conf|
# Needed to inject the current_user method into the model
config.security.current_user_method = :current_user
end

protected

# only authenticated admin users are authorized to create projects
def create_authorized?
user = current_user
!user.nil? && user.is_admin?
end

def current_user
@session[:user_id] ? User.find(@session[:user_id]) : nil
end
end

2 番目のレベルのセキュリティーを利用すると、より複雑な、データ専用のロジックを作成することができます。例えば、Projects は Organizations に所属 (belongs_to) するため、プロジェクトの編集を、そのプロジェクトを所有する組織の管理者のみに制限することは妥当です。このためには、モデルに authorized_for_#{crud_action} などのメソッドを追加します (ここで #{crud_action} は、createreadupdate、あるいは destroy のうちの 1 つです)。


リスト 23. モデル・ベースのセキュリティー
                
class Project < ActiveRecord::Base
belongs_to :organization

# Since projects are owned by an organization, allow only administrators
# of that organization to edit the project
def authorized_for_update?
organization.is_admin? current_user
end
end

current_user メソッドが利用できるのは、ActiveScaffold がこのメソッドを、対応するコントローラーの current_user_method の構成に基づいてモデルに注入するからであることに注意してください。




上に戻る


まとめ

Ruby のような動的言語では、Java ™ 言語や PHP のような静的言語では不可能な一連の機能を活用することができます。ActiveScaffold は、いくつかあるモデル・ベースの「スマート」UI システムの 1 つであり、データ入力ページの作成や維持管理を劇的に単純化することができます (スマート UI システムのリストは下記の「参考文献」を参照しください)。

私のブログに投稿して、皆さんの考えを教えてください。





上に戻る


ダウンロード

内容ファイル名サイズダウンロード形式
Source code for Rails projectIntroAS-sample.zip101KBHTTP
ダウンロード形式について


参考文献

学ぶために

製品や技術を入手するために
  • 2枚組 DVD セット、SEK for Linux をご注文ください。DB2® や Lotus®、Rational®、Tivoli®、WebSphere® など、Linux 用の最新 IBM ソフトウェアの試用版が含まれています。

  • 皆さんの次期 Linux 開発プロジェクトを IBM trial softwareを使って構築してください。developerWorks から直接ダウンロードすることができます。


議論するために


著者について

author photo

Mike Perham は IBM のシニア・ソフトウェア・エンジニアであり、WebSphere Business Services Fabric に従事しています。彼は Apache プロジェクトのメンバーであり、1995 年以来オープンソースのソフトウェアを開発してきました。彼はオートバイ・レースが好きであり、また新しい技術、特に Web ベースのアプリケーションの構築を容易にする技術を学ぶことが好きです。




記事の評価


サイト改善のため、ご意見をお寄せください。こちらのフォームからお願いいたします。



 


 


不充分・不完全である大変素晴らしい
 


この記事を共有する

del.icio.us del.icio.us newsing newsing FC2ブックマーク FC2ブックマーク
Choix! Choix! ニフティクリップ ニフティクリップ Yahoo!ブックマーク Yahoo!ブックマーク
MM/memo MM/memo CZブックマーク CZブックマーク livedoorクリップ livedoorクリップ
はてなブックマーク はてなブックマーク Buzzurl(バザール) Buzzurl(バザール)




上に戻る


DB2、Lotus、Rational、Tivoli、WebSphere は、IBM Corporation の商標です。 Java およびすべての Java 関連の商標およびロゴは、Sun Microsystems, Inc. の米国およびその他の国における商標です。 Linux は、Linus Torvalds の米国およびその他の国における商標です。Microsoft、Windows、Windows NT、および Windows ロゴは、Microsoft Corporation の米国およびその他の国における商標です。 他の会社名、製品名およびサービス名等はそれぞれ各社の商標です。 他の会社名、製品名およびサービス名等はそれぞれ各社の商標です。

    日本IBMについて プライバシー お問い合わせ