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

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

Model同士の関係をグラフで表示するプラグイン」に、かずひこさんのコントリビューションをマージしました。

新たに、モデル同士の関係図を出力する rake タスクが加わりました。以下のようにして使用します。

$ rake model_graph [FORMAT=jpg] 
FORMATの指定は省略可能です。

プラグインリポジトリはこちらになります。ご自由にご利用ください。

http://svn.labs.drecom.jp/rails/plugins/trunk/model_graph/
バージョン番号を振っていなかったので、もともとのバージョンを0.1として、今回のリリースはバージョン0.2という事にしておきます。

かずひこさん、どうもありがとうございますー。

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

posted by Png genki on Mon 4 Sep 2006 at 22:52

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

度々忘れがちなので備忘録。

ActiveRecordのhas_manyアソシエーションなどを使うと、コレクションに対するアクセサが追加されます。

class Group < ActiveRecord::Base
  has_many :members
end
このとき、コレクションに対して以下のようにARオブジェクトを追加すると、
group.members << Member.new(params[:member])
group.new_record?が真の場合はMemberはそのままコレクションに追加され、DBは変化しませんが、group.new_record?が偽の場合は、Memberは直ちにsaveされ、DBに格納されます。

group.new_record?が偽の場合にDBを変更せずにMemberをコレクションに追加したい場合は、以下のようにbuildメソッドを利用します。

group.members.build(params[:member])
余談ですが、リソース系のオブジェクトはcreateよりもnewを使う事が多いですね。 Ajaxでちょっとずつリソースを作っていって、完成したところでsaveでDBに格納。 逆にActivity系のオブジェクトは、createで作成と同時にDBに格納する感じです。

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

posted by Png genki on Mon 4 Sep 2006 at 17:45