Rails2.0でscaffoldを行うと、HTMLと同じURL+.xmlでXMLの取得も行えます。リソースひとつだけ取得するのであればこのままでも大丈夫なのですが、たとえばuserとblogが1:nの関係で、userのXMLを取得する時に同時に複数のblogも取得したい場合どのようにすればよいのかわかりませんでした。
to_xmlを使わずテンプレートでがんばろうかなと思っていたところ、1年前のRyan’s Scrapsでまさにそのものな:includeオプションを見つけました。
1 2 3 4 5 6 7 | @user = User.find(1) @out = @user.to_xml(:include => :blogs) respond_to do |format| format.html # show.html.erb format.xml { render :xml => @out } end |
scaffold後に↑のようなソースになりますが、2行目でto_xmlのオプションに:includeを付与しておくと、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?xml version="1.0" encoding="UTF-8"?> <user> <id type="integer">2</id> <login>ホゲ</login> ~ 中略 ~ <blogs type="array"> <blog> <created-at type="datetime">2008-06-10T15:06:14+09:00</created-at> <id type="integer">1</id> <user-id type="integer">2</user-id> <title>ホゲブログ1</title> <updated-at type="datetime">2008-06-10T15:06:14+09:00</updated-at> </blog> <blog> <created-at type="datetime">2008-06-10T15:36:23+09:00</created-at> <id type="integer">5</id> <user-id type="integer">2</user-id> <title>ホゲブログ2</title> <updated-at type="datetime">2008-06-10T15:36:23+09:00</updated-at> </blog> <blogs/> </user> |
のように、userの子要素として blogs > blog が追加されました。
そのほか to_xml には :include 以外にも便利なオプションがあります。
たとえば不必要な項目を除外する:except、指定項目だけを表示する:only。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | user = User.find(1) user.to_xml(:except => [:id, :created_at]) #=> # <user> # <name>Ryan</name> # <email>ryan@spamme.com</email> # </user> user.to_xml(:only => [:email]) #=> # <user> # <email>ryan@spamme.com</email> # </user> |
また、下記のようにXMLにエレメントを追加することもできます。この例ではidとcreated_atを除外して、serialize_versionを1.1として追加しています。
1 2 3 4 5 6 7 8 9 | user.to_xml(:except => [:id, :created_at]) do |xml| xml.serialize_version 1.1 end #=> # <user> # <name>Ryan</name> # <email>ryan@spamme.com</email> # <serialize_version>1.1</serialize_version> # </user> |
あー便利だなあ。

