2011-02-21

今さらRails3メモ - その2 : C, V を中心に -

とりあえず 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既存レコードの削除

となっている。やってることは

  1. Model インスタンスを作る(.all(), .find(), .new())
  2. 必要な処理を加えて
  3. 結果を返す(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 にまたがる場合はどうするんだろう? 宿題。

  1. Test::Unit ではなく RSpec を使う設定になっているものとする。 

About

例によって個人のなんちゃらです

Recent Posts

Categories

Tool 日々 Web Biz Net Apple MS ことば News Unix howto Food PHP Movie Edu Community Book Security Text TV Perl Ruby Music Pdoc 生き方 RDoc ViewCVS CVS Rsync Disk Mail FreeBSD Cygwin PDF Photo Zebedee Debian OSX Comic Cron Sysadmin Font Analog iCal Sunbird DNS Linux Wiki Emacs Thunderbird Sitecopy Terminal Drawing tDiary AppleScript Life Money Omni PukiWiki Xen XREA Zsh Screen CASL Firefox Fink zsh haXe Ecmascript PATH_INFO SQLite PEAR Lighttpd FastCGI Subversion au prototype.js jsUnit Apache Trac Template Java Rhino Mochikit Feed Bloglines CSS del.icio.us SBS qwikWeb gettext Ajax JSDoc Rails HTML CHM EPWING NDTP EB IE CLI ck ThinkPad Toy WSH RFC readline rlwrap ImageMagick epeg Frenzy sysprep Ubuntu MeCab DTP ERD DBMS eclipse Eclipse Awk RD Diigo XAMPP RubyGems PHPDoc iCab DOM YAML Camino Geekmonkey w3m Scheme Gauche Lisp JSAN Google VMware DSL SLAX Safari Markdown Textile IRC Jabber Fastladder MacPorts LLSpirit CPAN Mozilla Twitter OpenFL Rswatch ITS NTP GUI Pragger Yapra XML Mobile Git Study JSON VirtualBox Samba Pear Growl Mercurial Rack Capistrano Rake Win RSS Mechanize Sitemaps Android JavaScript Python RTM OOo iPod Yahoo Unicode Github iTunes God SBM friendfeed Friendfeed HokuUn Sinatra TDD Test Project Evernote iPad Geohash Location Map Search Simplenote Image WebKit RSpec Phone CSV WiMAX USB Chrome RubyKaigi RubyKaigi2011 Space CoffeeScript Nokogiri Hpricot Rubygems jQuery Node GTD CI UX Design VCS Kanazawa.rb Kindle Amazon Agile Vagrant Chef Windows Composer Dotenv PaaS Itamae SaaS Docker Swagger Grape WebAPI Microservices OmniAuth HTTP 分析基盤 CDN Terraform IaaS HCL Webpack Vue.js BigQuery Middleman CMS AWS PNG Laravel Selenium OAuth OpenAPI GitHub UML GCP TypeScript SQL Hanami Document SVG AsciiDoc Pandoc DocBook Develop Jekyll macOS Node.js Vite Heroku Transformer AI Data Cloud Wasm