とりあえず scaffold する
最初は様子がよく分からないので
r g scaffold
しちゃう。
scaffold は一躍 Rails を有名にしたものなんだけど、これは何より様子を掴むのに向いている。例えば
r g scaffold example name:text
とすると
- カラムを1つ ( name ) 持つテーブル1つ ( example ) に対応するモロモロ
を作ることができる。
実際に実行するとファイルでこれだけのものができる1。(routes はファイルができたんじゃなくて routes.rb を書き換えたよの意味。)
invoke active_record
create db/migrate/#{SERIAL}_create_examples.rb
create app/models/example.rb
invoke rspec
create spec/models/example_spec.rb
route resources :examples
invoke scaffold_controller
create app/controllers/examples_controller.rb
invoke erb
create app/views/examples
create app/views/examples/index.html.erb
create app/views/examples/edit.html.erb
create app/views/examples/show.html.erb
create app/views/examples/new.html.erb
create app/views/examples/_form.html.erb
invoke rspec
create spec/controllers/examples_controller_spec.rb
create spec/views/examples/edit.html.erb_spec.rb
create spec/views/examples/index.html.erb_spec.rb
create spec/views/examples/new.html.erb_spec.rb
create spec/views/examples/show.html.erb_spec.rb
invoke helper
create spec/helpers/examples_helper_spec.rb
create spec/routing/examples_routing_spec.rb
invoke rspec
create spec/requests/examples_spec.rb
invoke helper
create app/helpers/examples_helper.rb
invoke rspec
invoke stylesheets
create public/stylesheets/scaffold.css
上から
- db の migration
- model
- model の spec
- routing ( 一通り CRUD できるように resources になっている )
- controller
- controller の各メソッドに対応する view
- controller の spec
- view の spec
- helper の spec
- routing の spec
- requst の spec
- helper
- stylesheet
となっている。このまま
rake db:migrate
r s
すると
http://localhost:3000/examples
にアクセスして実際に使える。
Controller
layout
layout "NAME"
layout ファイルを指定できる。何も指定しなければ
app/views/layouts/application.html.erb
が選択される。
※ jpmobile が有効で mobile な user agent だったら
app/views/layouts/application_mobile.html.erb
などになる。
さっき scaffold したコードを読む
Controller には index, show, new, edit, create, update, destroy のメソッドがある。それぞれ
index | 一覧表示 |
show | 個別表示 |
new | 新規追加form表示 |
edit | 既存レコードの編集form表示 |
create | 新規追加送信先 |
update | 既存レコードの編集結果送信先 |
destroy | 既存レコードの削除 |
となっている。やってることは
- Model インスタンスを作る(.all(), .find(), .new())
- 必要な処理を加えて
- 結果を返す(render(), redirect_to(), head( :ok ))
以上。
Skinny Controller !
respond_to と format.xml の部分はとりあえず気にしなくていいと思う。たぶん。
View
Controller を読むと分かるけど View ってオブジェクトを明示的に作ることはない。
※ erb 以外のテンプレートは使ったことがないので知らない。
基本的なテンプレートの配置
app/controllers/#{controller}_controller.rb
app/views/#{controller}/#{action}.html.erb
controller のメソッド名に対応した view が勝手に呼ばれる。
見ると分かるけど先ほどの scaffold で指定した field ( name ) がちゃんと index, show, _form にハマっている。
ここでもう一度 Controller と見比べると
- params[:example]
- @example
- @examples
- example.name
などの意味するところが見えてくると思う。
partial の扱い
(主に V や Helper で)
render 'NAME'[, { 渡すオブジェクトのマップ }]
と指定するとこれを呼んだ View と同じディレクトリの
File.dirname( __FILE__ ) + "/_#{NAME}.html.FORMAT"
を探しにいく。例えば上で scaffold した例だと
app/views/examples/edit.html.erb
app/views/examples/new.html.erb
に
<%= render 'form' %>
と書かれている。実際に呼び出されるのは同じディレクトリにある
app/views/examples/_form.html.erb
になる。
※ オブジェクトのマップについては後述。partial の呼び出しは Rails 3 で簡略化されたので 2 以前の知識のある人、2 以前を対象にした本を参考にしている人は注意。
partial を別なディレクトリに置く
partialの名前に / が入ると app/views/ 以下のどこかのパスのpartialを探しにいく。
View から見えるもの
View から Controller の持っているものは基本的にすべて見える。request, params, cookies, response, session, headers など。Controller で Model のインスタンスをインスタンス変数に持っているなら、V からもそれが見える。
だから index.html.erb で @examples.each と書いてすべてのレコードの一覧を表示することができるし、_form.html.erb でいきなり @example を参照して form を組み立てることができる。
というか `controller' で Controller そのものにもアクセスできる。つまり全部見える。テンプレートで
<%= debug( controller ) %>
として見れば分かる。
partial に渡るオブジェクトと partial の動き
partial の書き方はいろいろあるので、本当に細かいところは
Ruby on Rails Guides: Layouts and Rendering in Rails
に譲るとして、とりあえず
- インスタンス変数は何もせずにアクセスできる
- ローカル変数へのマップは :locals で明示する
- :collection を使うとループの処理書かなくてもいい具合に動く
- :action で他の action 呼び出して結果を返せる
くらいは分かっておくとよい。
HTML は helper で書くより partial の方が楽かも?
ActionView::Helpers::TagHelper
に
- content_tag
- tag
という便利メソッドがあって HTML の組み立てもラクチンにできそうだけど、デフォルトでエスケープされるし
<%= %>
は Rails 3 以降デフォルトでエスケープされるので注意が必要。とは言え動的に何か組み立てようと思ったら Helper に書いた方が見通しはよくなるので、
<%= raw helper_method %>
みたいな形に落ち着くのかな。でもこの代わりにも partial が使えるような。
<%= yield :NAME %>
<%= render 'name' %>
とやって partial の方で
<%
content_for :NAME do
...
end
%>
とか。
jpmobile が有効な場合、partial に対してもテンプレートの切り替えが有効なので、Controller や Helper で分岐を書く必要がなくなって嬉しい気がする。
form
この辺を見る。
- ri ActionView::Base
- ri ActionView::Helpers
- ri ActionView::Helpers::FormBuilder
- ri ActionView::Helpers::FormHelper
- ri ActionView::Helpers::FormOptionsHelper
- ri ActionView::Helpers::FormTagHelper
form_for が form_builder を作るメソッド。
form_for( @model ) do |f|
f は FormBuilder が渡ってきている
end
Model.columns を使うと column 情報は取れるので、手動で作る分にも雑な form ならすぐに作れそう。
二つの Model にまたがる場合はどうするんだろう? 宿題。
Test::Unit ではなく RSpec を使う設定になっているものとする。 ↩
文字コードとか考えてません。最初 gawk で書いてたけど match() でマッチした文字列を配列で受け取れるgawk拡張について
3.1.5 はバグ持ちだよ
という記述を見つけてしまって凹んでました。というか手元の 3.1.4 で試して動いたんだか動かないんだかよく分からなくて放り投げてしまいました。awk スクリプトで最新版を要求するなんて優しさが足りない。
Therefore use:
echo test4325363test | gawk 'match($0, "([^0-9]*)([0-9]+)(.*)", a) { print a[2] }'
to extract the number.
Please, note that gawk 3.1.5 has some bugs in the match function. These should be corrected in gawk 3.1.6 (see ftp://ftp.gnu.org).
How to gram awk's regexp submatches? - Object Mix
というわけで Ruby に鞍替え。
なんか諸々 CSV に決め打ちで TSV とか対応できませんけど勘弁してちょ。optparse で delimiter 受け取って動的に正規表現作ればイケますよ、とだけ書いてお茶を濁しておく。
途中、範囲式からループを回す処理は見慣れないと気持ち悪いけど、なぜか Ruby を書いていると i += 1 とかカウンタを自分でいじる方が気持ち悪いと感じるようになるのです。for ( ; ; ) 文がないので while の中で自分でカウンタいじることになるんだけど、そうするとインクリメントのタイミングによって値が変わっちゃうとかそういう落とし穴を作ることになるんでやりたくなくなるのです。do end と { } が混ざっているのはごめんなさいということで。
#! /usr/bin/env ruby
class Csv2Fixed
def initialize
@num_fields = 0
@num_lines = 0
@len_cols = []
@buf = []
end
def run
while ( line = gets )
arr = split_csv( line.chomp )
if ( arr.size > @num_fields )
@num_fields = arr.size
end
store_line( arr )
@num_lines += 1
end
output()
end
def store_line( arr )
@buf[@num_lines] = []
(0 ... arr.size).each do |i|
str = arr[i]
if ( @len_cols[i].nil? or str.size > @len_cols[i] )
@len_cols[i] = str.size
end
@buf[@num_lines].push( str )
end
end
def output
(0 ... @num_lines).each do |i|
arr = @buf[i]
(0 ... arr.size).each do |j|
printf( "%-*s ", @len_cols[j], @buf[i][j] )
end
printf( "\n" )
end
end
def split_csv( str )
str = str + ","
arr = []
str.scan( /(\"(?:[^\"]|\"\")*\"|[^,]*),/ ).each { |e|
arr.push( e.to_s.sub( /^"/, '' ).sub( /"$/, '' ).sub( /""/, '"' ) )
}
return arr
end
end # of class Csv2Fixed
if ( __FILE__ == $0 )
app = Csv2Fixed.new()
app.run()
end
なんかちと疲れたべ。
Rubyist Magazine - Rubyist Hotlinks 【第 13 回】 関将俊さん
咳 まずは。ふだんもう立ち上げっぱなしで。
須藤 えーっ。そうだったんですか。
咳 irb 端末が一個。
一同 (笑)
笹田 じゃあ、Ruby がどうのっていうわけじゃなくて?
咳 Smalltalk の workspace みたいなかんじで繋げっぱなしで、例えば今のイテレーションの状況とかって計算するときに irb から直接 RWiki に繋いで結果ばーって。
笹田 あー、なるほど。すげーかっこいい。
須藤 かっこいい。
角谷 かっこいい。
かっこいい。分かんないけどかっこいい。
前の方にも書いてあるけど RWiki は RD → HTML ということだけではなくて、Ruby のオブジェクトを保存しているイメージなんだそうだ。中身見る気力があるかどうか分からないけど、動かすだけ動かしてみようかな。ひょっとするとものすごく便利かもしれない。1記法の問題は残るけど(結局それか)。
[2006-02-22 追記]動かす方が気合い要りそうだったのでやめた。
前から細かくメタ情報が残ってて便利だなとは思ってたけど。 ↩
まず、現在「ruby 1.7 feature」「ruby 1.8 feature」というのが残っている問題について。これは現状では不要であるが、Ruby 1.6 のリファレンスがないために残っている。そこで、1.6 版の最終版として、どこかの時点で凍結したものを用意し、入手できるようにしておく。そして、今後編集していく本体の方からはすべての「ruby 1.7 feature」「ruby 1.8 feature」を削除すればよいだろう。
なお、1.9 feature については、そのまま残しても構わないが、無理につけ加える必要もないので、必要に応じてつけていくことになるだろう。まずは 1.8 の安定版のマニュアルを作ることを優先するべき、という判断の元、1.9 への対応については今後の課題とする。
これ実は個人的には結構気に入っている記述だったんだけど…。
PHP のマニュアルもこんな感じになっていて、あーこの関数は PHP 4.3 からだったのかーちくしょう、とかこれは 3 から使えてたのか、へー知らなかったな、これは 4.2 から挙動が変わったのか、じゃあここはこうしなきゃダメじゃないか、てなことを思いながら参照している。
まぁ 1.6 対応のスクリプトを書くときは 1.6 用のマニュアルを見ればよいという割り切りができる方が普通は楽なのかなぁ。なんか寂しいというか、自分にとっては使い勝手が悪くなってしまうような気もして怖い。マニュアルを2つ用意しなきゃならないという面倒くささもある。1.6 の環境だけの人、1.8 の環境だけの人は別になってると楽だけど、両方使ってる自分にとってはマニュアルが分かれるのはあんまり嬉しくないような気がするなぁ。
日本Rubyの会は世の中で Ruby に触ったことのある人たちよりも絶対にベテランで、かつ環境も新しいものに結構よく追いついて行っている方だと思われるので、1.8 以降の記述に集中したいっていうのは分からなくもない。まぁ「まずは 1.8 の安定版のマニュアルを作ることを優先するべき」という課題に最短距離で向かうためには切り離した方が作業はしやすいか。そうだよな。
で、このページの筆者の方がインターネット調査は社会調査に利用できるかという報告書に以下のように突っ込んでいるが、
- 1つの設問は1つのスクリーンに収まるように
- ユーザの環境によって画面の広さは異なる。基準(例えばSVGA)を決める必要がある。
広さと「設定」によって異なりますぜ。今じゃ携帯だって高精細だから設定次第で結構な文字数を表示できるし、ウィンドウを全画面表示で横長に使っているとも限らない。
というツッコミは意地悪半分、本気半分。今回は報告書の言ってることは概ね正しいけど実現するのは楽じゃないよという話なわけですが、方法としては以下のような感じ?
- (昔デザイナのサイトで流行った)新規ウィンドウを開いて固定サイズのフォントを使う
- JavaScript と CSS で動的にサイズ調整
- Flash とか Java とか PDF でリッチクライアントの操作性に期待する
あるいは
- S5 のように JavaScript と CSS を使って長い HTML の1ページを複数のスクリーンに分割する
と、いちいちサーバと通信せずに JavaScript に情報を保存できるし、Flash や Java のように plugin を必要としないし、ユーザーの意思で JavaScript を off にして(あるいは JavaScript 非対応のブラウザを使って)長い HTML のページと格闘することも可能だから、これがいちばんいいのかも。でも S5 って自分自身が作りだすナビゲーションやスライドショーで実際に表示する内容以外はまったく考慮されてないから、他のコンテンツへのナビや広告も盛り込みたいって要求になった場合はちょっと使いにくいか。そこのサイトのナビや広告が CSS の管理下にあればいいけど、そうでないとダメくさい。
生 HTML は操作性があまりよくないが、plugin 前提の場合は操作性はよくなるがユーザーの環境を限定してしまうという問題って、他にもいろんなシーンがあるわけですが、この調査票ネタはそれを考えるのにとてもよい題材かもしれない。
素晴らしい! RD のままっつーのもあるけど、これは、、、自前の RWiki で再現しろとか自分で RDTool とか使って好きにしろとかそういうことかな?(^^;
今までも 1.8 対応の HTML 版は非公式にはありましたけど、本家にあるってのが重要ですね。さーて早速手元のものをこれで更新すっかー。Ruby を書く予定はないけど。。。
あれ、リファレンスマニュアルのトップページから参考文献とか参考になるサイトへの誘導がありますね。前からこんなのあったかな。整理されているし、るびまの入門記事へのリンクもありますね。いい感じですね。
e-Learning は学習者の要求、学習者と(居るとして)指導者の関係、学習内容などに応じて様々な形があるので、「これが正解」という一つの形は存在しない。ビジネスの文脈で語られる e-Learning は予備校の衛星授業みたいなものだが、exCampus の目指すところはどこにあるのか。大学で実験してるんだから高等教育以上になるのかな。
オープンソースな学習支援ということで、面白い企画だと思う。コケないでほしいね。ある意味学会などより確実にノウハウの共有が進むし。