ブラウザ以外のUserAgentからRailsアプリケーションにリクエストを送る場合、Railsが管理しているsessionの仕組みとは別に、自分でセッションをセットアップしたくなる事があります。

そのような場合は、たとえばクエリパラメータからsession_idを渡したりするのですが、GET methodで受け渡したsession_idからRailsのsessionを再現するためには、以下のように記述します。

   1  FooController < ApplicationController
   2    session :off, :if => (proc do |req|
   3      return false unless req.parameters[:action] == 'bar'
   4      if req.parameters[:session_id]
   5        @original_session_options = req.session_options
   6        req.session_options[:session_id] = req.parameters[:session_id]
   7      end
   8      false
   9    end)
  10    prepend_before_filter :only => 'bar' do
  11      if @original_session_options
  12        @original_session_options[:session_id] = nil
  13      end
  14    end

before_filterを使っていないのは、before_filterでは Railsのsession処理に間に合わないためです。

更新履歴

  • 2007/11/20 不具合があったため内容を修正しました
posted by Png genki on Tue 20 Nov 2007 at 04:17

Rails勉強会@東京#02-24

Genki Takiuchi

Recent Situation:

  • Founded small company.
  • Moved to Shindaita from Ebisu.
  • Became slightly familiar with MAC.
  • And also with Rails 2.0

Favorite Things:

  • C/C++ Template, JavaScript, Ruby.
  • Thinking algorithm, Rendering (CG) and 3D.
  • Vim7, Zsh, GNU screen, rails.vim, ZenTest.

Thank you!

posted by Png genki on Sun 18 Nov 2007 at 08:49

画面の内容に合わせて、必要なJavaScriptやStyleSheetをincludeする場合、 以前紹介した content_forを使うのが便利ですが、 画面内で何度も呼び出される partial のなかに記述したりすると、 呼び出された回数分だけ include されてしまったりして不便です。

そこで、画面内で一回だけ content_for を実行するためのプラグイン、 content_for_once を作りました。こちらに置いてあります。

使い方。まずはプラグインをインストールします。

   1  % ./script/plugin install https://svn.s21g.com/public/rails/plugins/content_for_once/

あとは、Viewから以下のようにして呼び出します。

   1  <% content_for_once :head do %>
   2    <%= javascript_include_tag 'iepngfix' %>
   3  <% end %>

これで、このコードが実行されたときに、一度だけJavaScriptが includeされるようになります。

posted by Png genki on Sun 18 Nov 2007 at 04:54

Ultraviolet によるシンタックス・ハイライトに対応しました。

書式は以下のような感じです。

ruby>>
def foo
  bar
end
<<--

レンダリング結果は以下のとおり。

   1  def foo
   2    bar
   3  end

posted by Png genki on Sun 18 Nov 2007 at 04:22

会社設立や、それに伴う環境の変化への対応などのため、しばらく開発がとまってしまっていた ShootingStar ですが、ipod touch&iphoneへの対応作業をほぼ完了いたしました。

DEMO: http://www.cocktail-party.jp/

screen shot

もうしばらくコードの整理をしてから、version 3.2.5 をリリースいたします。

よろしくお願いいたします。

posted by Png genki on Sat 17 Nov 2007 at 18:52

Core Services社が提供している DebugBarCompanion.JS を使って、IE6のデバッグ環境を改善してみた。

ScreenShot1

DebugBarは、ツールバー(DeskBand)とサイドバー(InfoBand)を使ったIE拡張で、DOM Inspector的な機能がある。Companion.JSは、CommBandを使ったIE拡張で、Script Console機能を持っている。

IEのJavaScriptデバッグには、本当に難儀していたので有難い。

posted by Png genki on Sat 17 Nov 2007 at 09:41

以前、ログをトレースしながらautotestを走らせる方法を紹介しましたが、 今回はさらにその方法を拡張して、script/consoleも同時に実行してしまう 方法を紹介します。

ちなみに以前紹介した方法は、こんな感じでした。

% tail -f log/development.log &
% autotest

tail -f log/development.log &でloggerの出力をバックグラウンドで補足しつつ、フォアグラウンドではautotestを実行しています。

今回は、autotestもさらにバックグラウンドで起動させて、 フォアグラウンドで./script/consoleを実行させるのですが、 一つ問題があります。

autotestは、migrationの実行などでDBの中身が変わった場合など、 Ctrl+CでINTを送ってリロードさせる必要があるのですが、 バックグラウンドプロセスにしてしまうと、Ctrl+Cでリロード できなくなってしまいます。

そこで、autotestのリロードを script/consle の中から行えるように するプラグインを作りました。

インストール方法は、通常のRailsプラグインと同様です。

% ./script/plugin install http://svn.s21g.com/public/rails/plugins/trident/

使い方は、モニタリング用のコンソールから以下のRakeタスクを実行します。

% rake trident

すると、tail -f log/development.logautotestが実行され、 script/consoleが立ち上がります。

この状態で、autotestをリロードさせる場合、script/consoleから

> Trident.reload

を実行すればOKです。

終了するときは、普通にscript/cosoleexitすると、生成された子プロセスと一緒に終了します。

posted by Png genki on Fri 16 Nov 2007 at 06:51

こちら で、ExceptionNotifierプラグインのテンプレートに関するバグの報告が出ていました。

Plugins - Exception Notifier

Brett Neumeier 12 Oct 2007

In ruby 1.8.6p111, rendering the _environment.rhtml plugin fails with "TemplateError: flag after width". This is fixed if you change the string "%-s" to "%-s" on line three of the template.

Chris 18 Oct 2007

This is the correct string: "%-*s:"

具体的には、views/exception_notifier/_environment.rhtml の3行目を次のように修正すればOKのようです。

views/exception_notifier/_environment.rhtml

<% max = @request.env.keys.max { |a,b| a.length <=> b.length } -%>
<% @request.env.keys.sort.each do |key| -%>
* <%= "%-*s: %s" % [max.length, key, filter_sensitive_post_data_from_env(key, @request.env[key].to_s.strip)] %>
<% end -%>

手元の環境(ruby-1.8.6 p36/Rails-1.99.0)では、これで問題なく動作するようになりました。

posted by Png genki on Thu 15 Nov 2007 at 05:07

Railsのプラグインは非常に便利な仕組みなのですが、pluginのテスト とうまく付き合うにはちょっと工夫が必要です。

plugin用に書かれているテストは、二通りの方法で実行される可能性があります。

  1. plugin ディレクトリの中で rake コマンドた実行された場合
  2. RAILS_ROOT から rake test:plugins が実行された場合

いくつかのプラグインは、上記の片方のケースのみを想定して test が書かれている場合があり、想定されていないケースからテスト が実行された場合、多くは沢山のエラーを出すようになります。

このような場合、プラグインディレクトリのRakefileに手を加えて、 呼び出し元に応じて処理を分けたりすれば、一見うまくいきそうですが、 そう簡単にはいきません。

Railsの test:plugins の仕組みは、プラグインディレクトリの Rakefileを参照せずに、直接 test ディレクトリの中身を実行する からです。

この挙動はあまり良くないと思うのですが、とりあえず、 rake test:plugins から実行するとエラーを出すプラグインの テストディレクトリの名前を plugin_test 等に変更して、 プラグインのRakefileを以下のように書き換えることで回避できます。

Rakefile

   1  desc 'Test the acts_as_taggable_on_steroids plugin.'
   2  Rake::TestTask.new(:test) do |t|
   3    t.libs << 'lib'
   4    t.pattern = 'plugin_test/**/*_test.rb'
   5    t.verbose = true
   6  end

これによって、上記 1 のケースでは正常に動作し、2 のケースではSkipされるため、エラーの山を見ることから逃れられます。

posted by Png genki on Thu 15 Nov 2007 at 02:13
undefined method `<<' for nil:NilClass
posted by Png genki on Thu 15 Nov 2007 at 01:34