This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/105

今月もRails勉強会@東京に参加してきました。前回に引き続いてドリコム東京オフィスでの開催でした。勉強会の開催も今回で二桁に突入ですね。参加者の数も多くなってきて盛況です。

さて、今回も前半・後半に分かれてオープンスペース形式で行われました。前半は「Rails1.2を先取り」、後半は「Capistrano1.2」に参加しました。

■Rails1.2を先取り

Rails1.1.6から現在までのChangeLogを淡々と読んでいきました。

実際読んでみると、Rails本体に対しては大きな機能追加はほとんど無く、script.aculo.usやprototype.js周辺に機能追加が多かった印象です。特にActiveRecord周辺はほとんど変更されていませんでした。

とはいえ、細かい修正点はたくさんあり、すべては紹介しきれないので、いくつか面白そうなものだけピックアップしておきます。

□link_to_functionがブロックをとるようになった

link_to_functionがブロックを指定できるようになり、 

link_to_function("Show me more", nil, :id => "more_link") do |page|
  page[:details].visual_effect  :toggle_blind
  page[:more_link].replace_html "Show me less"
end
というようなことができるようになります。クライアントサイドで完結するような静的なエフェクトは、こうやって直接書いたほうがよさそうですね。

□String#to_jsonが高速化

前田さんのパッチが採用されて、長い文字列のto_json呼び出しが高速化されました。

また、Rails1.2ではまだ本体に取り入れられない可能性が高いですが、ActiveResource関連のコミットもたくさんありました。

■Capistrano1.2

序盤はCapistrano(旧SwitchTower)の基本的なことを振り返りました。 

後半は、Capistrano1.2のChangeLogを読みつつ、確かRails勉強会#2ぐらいでしたでしょうか、gorouさんの「SwitchTowerの光と影」というセッションで語られた影の部分が1.2ではどうなってるんだろう、というあたりを検証しました。

Capistrano1.2の新機能としては、web, app, dbの3種類以外ののロールを追加できるようになったのが面白いですね。あとは、スレッドを使って複数台のサーバを並列に処理するようになったようです。

ただ、肝心の影の部分はあんまり改善されていないような感じです。パスワード認証の場合はパスワードを統一しないといけないし、鍵認証にする場合にkeychainが使えず、サーバ上に秘密鍵を置いておかないといけなかったり、という部分ですね。

■懇親会
懇親会では、主にmaihaさんやyamazさんと話していました。
アーロンチェアの話題が盛り上がってましたね。やはりエンジニアにとって椅子は重要。

あと、RailsChatで話題になっていたdelegateの話とか。オブジェクトに対するdelegationではなくて、決まった値や関数に対するdelegateの方法として、

class Foo
  delegate :bar, :to => "5#"
end 

Foo.new.bar #=> 5
のように記述すれば良いんじゃないかと提案したところ、maihaさんが喜んでくれたのでよかったです。あきらかに反則技ですが。

This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/105

posted by Png genki on Mon 25 Sep 2006 at 12:20

This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/104

しばらくRuby on Railsを使ってきて、あったらいいなあという機能がいくつか出てきたので、時間ができたときのためにメモ。

script/rename
クラス名とかモジュール名を簡単にリネームできる機能が欲しいですね。 現状はなかなか面倒なので、最初にクラス名を決めるときに結構悩んでしまいます。 script/generateみたいにsvnを考慮してリネームしてくれると素晴らしいですね。
renderキュー
renderの呼び出しをキューに保存しておいて、after_filterで良い感じにマージして出力してくれる機能。キューが空っぽならrender :nothing => trueですね。 メソッド名はdefered_renderとかかな。
まだあったような気がしますが、思い出せなくなったのでまた今度。

This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/104

posted by Png genki on Sun 24 Sep 2006 at 01:02

This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/103

新しいアルファサービスとして、DrecomWantedがオープンしました。

開発に関わった皆さん、ひとまずお疲れさまです!

This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/103

posted by Png genki on Thu 21 Sep 2006 at 13:03

This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/102

Document/Viewアーキテクチャでは、Documentが変更されると、Viewが無効化されて再描画されるような機構が備わっています。

Ruby on Railsでも、ModelとViewの関係を明確化して、Modelの変更をafter_updateで検知してJuggernautでクライアントに通知し、JavaScriptで対応するViewの表示を更新するような機構があればスマートかも。 ModelとControllerを一対一対応にして(ActiveResourceとも相性が良さそう)、 ビューに階層構造を持たせる感じですね。

Alexから聞いた話だと、Juggernautの次のリリースはかなり良い感じになるみたいなので、それが出たらちょっと作ってみたいような。

This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/102

posted by Png genki on Wed 20 Sep 2006 at 12:10

This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/101

Ruby on Railsでは、コントローラの挙動をテストするためにFunctionalテストという仕組みがあります。 実際にページを取得し、レンダリング結果のタグを解析したり、リダイレクト先が正しいかどうか、指定したIDのタグが出力されているかどうか、などなど、様々なテストを行う事ができます。

そこで、ログインした状態でないとアクセスできないようなページのテストを記述するために、Cookieやセッションを使ってテストを記述する必要が出てきます。しかし、こちら(Rails - Functional Test with Cookie)で報告されているように、FunctionalテストでCookieを使用する方法には若干癖があり、ドキュメントも少ないようなので、使い方をまとめておきます。

Cookieを設定する場合は、@requestを通して以下のように行います。

@request.cookies['name'] = CGI::Cookie.new('name', value)
ポイントは、キー(name)としてシンボルを使わない事です。コントローラ内で参照する側では、シンボルを使って参照しても問題ない(to_sされている)のですが、Cookieを設定するテストコード側では、キーを文字列で指定する必要があります。 'name'を二度指定しなければならず、若干かっこ悪い感じですね。

ちなみに、コントローラ内から参照されるcookiesは、ActionController::CookieJarクラスのインスタンス変数です。 ところが、@request.cookiesはただのHashなので、その辺のミスマッチを埋めるためにこのような指定を行う必要が出てきます。

This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/101

posted by Png genki on Mon 18 Sep 2006 at 05:17

This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/100

IE7でJuggernautを使ったときにエラーが出るようなので、原因を調べてみました。

その結果、IE7では、script、embed、objectなどの特定のDOMエレメントに対して、innerHTMLに値を設定しようとするとエラーになるようです。

   1  document.createElement('script').innerHTML = 'alert(1)'; // エラー!

いまのところ、以下のように別なDOMエレメントのinnerHTMLにHTMLとして 埋め込む分には大丈夫なようです。

   1  var span = document.createElement('span');
   2  span.innerHTML = '<script type="text/javascript">alert(1)</script>';
   3  document.body.appendChild(span);
どんな意図があっての仕様変更なんだろう?

  <a id="BlogEntryExtend"></a>
  <span id="extended-text" /><p>

ともあれ、IE7に対応するようにJuggernautのJavaScriptを書き換えてみました。

   1  ---- code of public/javascripts/juggernaut.js ----
   2   
   3    _appendIECommandHandler: function() {
   4      var scriptbox = document.createElement('div');
   5      scriptbox.style.display = 'none';
   6      scriptbox.innerHTML = [
   7        '&lt;script language="VBScript"&gt;',
   8        '  on error resume next',
   9        '  Sub juggernaut_flash_FSCommand(ByVal command, ByVal args)',
  10        '   call myFlash_DoFSCommand(command, args)',
  11        '  end sub',
  12        '&lt;/script&gt;'].join("\n");
  13      document.body.appendChild(scriptbox);
  14    },
  15   
  16    _appendFlashObject: function() {
  17      var host = Juggernaut.host;
  18      var port = Juggernaut.port;
  19      var data = Juggernaut.data;
  20      var flashbox = document.createElement('div');
  21      flashbox.style.display = 'none';
  22      flashbox.innerHTML = [
  23        '&lt;object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ',
  24          'codebase="http://download.macromedia.com/pub/shockwave/cabs/',
  25          'flash/swflash.cab#version=5,0,0,0" id="juggernaut_flash"&gt;',
  26        '&lt;param name="movie" value="/juggernaut.swf?host=', host,
  27          '&port=', port, '&juggernaut_data=', data, '"&gt;',
  28        '&lt;param name="quality" value="high"&gt;',
  29        '&lt;embed src="/juggernaut.swf?host=', host, '&port=', port,
  30          '&juggernaut_data=', data + '" quality="high" ',
  31          'name="juggernaut_flash" swLiveConnect="true" ',
  32          'type="application/x-shockwave-flash" ',
  33          'pluginspage="http://www.macromedia.com/go/getflashplayer"&gt;',
  34        '&lt;/embed&gt;'].join('');
  35      document.body.appendChild(flashbox);
  36     },

作者のAlex氏にはパッチを送っておきました。

This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/100

posted by Png genki on Wed 13 Sep 2006 at 20:26

This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/99

yuguiさんのhas_one :throughはABD的にRailsを使うのには欠かせない存在です。 今回は、オリジナルのhas_one :throughを拡張して、Unsaved objectも扱えるようにしてみました。

class ActiveRecord::Associations::HasOneThroughAssociation <
  ActiveRecord::Associations::HasOneAssociation
private
  〜 略 〜
  def load_target
    if !loaded? && @owner.new_record?
      table_name = @reflection.through_reflection.table_name
      @target = @owner.send(table_name.singularize).send(@reflection.name)
    end
    super
  end
end
上記のコードをオリジナルのコードに追加すると、Unsaved objectに対しても、アソシエーションを参照することができるようになります。
member = Member.new
member.build_membership(:group => Group.new)
member.group
というわけで、yuguiさんお願いしますー。

This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/99

posted by Png genki on Mon 11 Sep 2006 at 23:31

This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/98

ブログの記事をエントリーと呼ぶかアーティクルと呼ぶかというお話。

Railsで書けばこんな感じになります。

class Blog < ActiveRecord::Base
  has_many :entries
  has_many :articles, :through => :entries
end
エントリーは「記入する」というアクティビティで、ブログと記事(Article)はリソースなので、ABD的に考えると何の呵責もなくすっきりと理解できますね。すばらしい!

This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/98

posted by Png genki on Mon 11 Sep 2006 at 15:13

This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/97

すでにあるかもしれないですが、gemのサブコマンド補完関数です。

_gem () {
  `gem help commands | grep '^  *' | sed 's/^ *//' | sed 's/  *.*//' | sed 's/^/compadd /'`
}

compdef _gem gem
時間ができたら zsh はもっと詳しく調べてみたいですね。

This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/97

posted by Png genki on Sun 10 Sep 2006 at 02:31

This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/96

ZenTestは、RubyのTDD(テスト駆動開発)フレームワークの一つです。 TDDを行うのに便利な機能がいろいろあるのですが、特にautotestが気に入っています。

autotestをRAILS_ROOTで起動しておくと、編集したファイルに関係があるテストだけを自動的に実行して、結果を表示してくれます。

以前紹介した、テスト結果の色付けをしてくれる「RedGreen」と併用すると、さらに気分良くTDDを行う事ができます。 どうしてもテストコードを書くのが面倒、という方にも是非お勧めしたい一品です。

インストールもGemからできるので簡単です。

# gem install ZenTest
あとは、RAILS_ROOTに.autotestファイルを作って(空っぽで構いません)
$ autotest
とやればOKです。コード編集用と テスト結果表示用にTerminalを二つ並べておくと見やすいです。

This article was migrated from http://rails.office.drecom.jp/takiuchi/archive/96

posted by Png genki on Fri 8 Sep 2006 at 02:39