ラベル ruby on rails の投稿を表示しています。 すべての投稿を表示
ラベル ruby on rails の投稿を表示しています。 すべての投稿を表示

2008年10月1日水曜日

passenger(mod_rails) でバーチャルホストを使わない複数アプリケーション動作



railsの実行環境としてこの春あたりから話題騒然のpassengerを試してみた。このとき、普通にアプリケーションを立ち上げるのはみんながやっているが複数のアプリケーションをディレクトリで切り替えるというのはあまり見なかったので簡単にまとめておく。

まず、apache + passenger のインストールだが、どこのblogにも書いてあるので省略する。

passengerのための設定までは終了したとして、この後にそれぞれのアプリケーションを動かすための設定を行う。アプリケーションを動かすために設定しないといけない項目はシンボリックリンクを含めると合計4カ所だ。

まず最初にやるべきことはrails のアプリケーションのシンボリックリンクを作ることである。rails アプリケーションそのものが存在するディレクトリはapacheを動かしているユーザで
アクセスできれば、documentrootの中にある必要はないようだ。さすがアプリケーション。

railsアプリの名前が tasklist だとするとtasklistの中のpublic をシンボリックリンクで
Documentroot内の適当な場所にリンクする。だいたいこんな感じになるだろう。

---
cd /WWWROOT/rails/
ln -s /home/name/tasklist/public tasklist
---

次に設定するべきところは railsアプリの routingだ。ここでアプリの中でindexを開いたときに動くべきコントローラが taskであり、最初にアクセスされるべきアクションがindexだとして設定をおこなう。ここでは railsのアプリケーションの中の config/route.rb に以下の行を追加する。

--
map.connect '', :controller => "task", :action => 'index'
--
そして、public内のindex.htmlファイルにアクセスされないように index.htmlを
削除ないし名前変更する必要がある。これをやらないとindex.htmlをアクセスしていつまでたってもアプリケーションにたどり着かないことになってしまう。
これだけの設定でrailsアプリ側の準備ができた。

最後は httpd.confに railsのアプリケーションのrootを伝える設定を書き加える。passenger の設定の下に以下のような行を加えよう。

---
RailsBaseURI /rails/tasklist
---

このあと apacheをリスタートした後ブラウザから、 http://hostname/rails/tasklist とアクセスすると無事にアプリケーションが立ち上がっていることが確認できるだろう。

今回のポイントはこの最後の操作で、 RailsBaseURI の行を増やすと複数のアプリケーションに対応できるということにある。railsアプリを設定し、シンボリックリンクを作り、httpd.confに RailsBaseURIを書き加えれば、同時に複数のアプリケーションを立ち上げることが可能になる点がポイントだ。

以上、簡単だが主に自分でまた半年後にやるときの参考になればとおもい記録しておこう。

2008年1月13日日曜日

Ruby on Rails で googlemapをかっこよく



今回はいつものハードウェアとは趣が違って web サービスのテクニックの話である。

ruby on rails上でgooglemapをつかった表示を行うときにすこし気の利いたインタラクティブな動作をさせるところがトピックである。

ruby on rails で googlemapを扱うのに使われる pluginとしてym4r/gm というのがある。geocodingもふくめ非常に簡単に使えるのだが、逆に細かいところに手がとどかない。

事の発端はgooglemapの地図上のマーカをクリックすると吹き出し形式でメッセージが見られるインターフェースを実装したのだが、マウスオーバーで見られるほうがいいのではないかという意見をこのblogの共著のYUO氏から貰ったことであった。

そこでこの機能を実現するためにgoogleを何時間かしらべたが、googlemapの使い方はわかったものの、railsでの ym4rを使った例は英語サイトもふくめて直接的な回答にはいきあたらず、ym4r開発者のサポートBBSでもほぼ1年ほど放置プレイだったので備忘録もふくめて書いておく。

googlemap上 でマウスをつかった特別なアクションを使うためにはaddListenerによってリスナを設定する必要がある。しかしながら、 ym4r/gm のコードをそのまま使ってマーカを設定するだけではこのような設定ができない。リスナを設定するためにはリスナになるオブジェクトを変数として代入し、バインドしてやる必要があるためだ。

declare_init をつかってオブジェクトを変数として宣言しなおしてやる必要がある。そしてこの後で、宣言された変数を使ってリスナを設定するのだが、このときに既存のメソッドは役に立たない。汎用につかえるrecord_initメソッドを使うことにより、 initializeのルーチンの中に自分で設定したjavascriptをそのまま書き込むことができるのでそれを利用することになる。


書き上げたコードの一部を切り出しておくと以下のようになる。

ポイントは markerを変数化するときに#{x.id} をつけることによりすべてのマーカで違う変数名を持つようにすることが1つ目である。もう1つのポイントとしては record_init をつかって直接 googlemapを動かすjavascriptのGEvent.addListener メソッドを記述するところである。また、 変数 pで生成している htmlの終端に改行がはいっていると地図のjavascriptのレンダリングがうまくいかないようなのでちゃんと partialなレンダリングをした後にchompすることを忘れないことが大切なようだ。

さらに今回はlistenerとして mouseover のほかに mouseout を設定することで、マウスがはずれると即座にウインドウが自動で閉じる処理を行っている。


実装例

marker = GMarker.new([x.lat,x.lon],
:title => " #{x.created_at.strftime("%m/%d-%H:%M")}" )
p = render_to_string(:partial => 'msg',
:locals => { :tag => tag , :pm => x }).chomp

@map.declare_init(marker,"marker#{x.id}")
@map.overlay_init(marker)
@map.record_init "GEvent.addListener(marker#{x.id},
'mouseover',
function(){marker#{x.id}.openInfoWindowHtml(\"#{p}\")}); "
@map.record_init "GEvent.addListener(marker#{x.id},
'mouseout',
function(){map.disableInfoWindow();
map.enableInfoWindow();}); "