using jQuery in Rails

公開日時 okkez Sat, 20 Feb 2010 02:00:00 GMT

最近 Rails で作っているウェブアプリケーションでは jQuery を使うようにしている。 なんとなくこうすれば良さそう、というのがわかってきたので書いておく。

google の jsapi を使う。 どこかのブログで見つけたコード片をちょっと変更したやつ。

module ApplicationHelper

  def google_jsapi_tag
    '<script type="text/javascript" src="http://www.google.com/jsapi"></script>'
  end

  def google_load_tag(name, version)
    %Q|<script type="text/javascript">google.load("#{name}", "#{version}");</script>|
  end

end

layout では以下のようにする。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
  <head>
    <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
    <meta http-equiv="Content-Script-Type" content="text/javascript" />
    <meta http-equiv="Content-Style-Type" content="text/css" />
    <%= google_jsapi_tag %>
    <%= google_load_tag 'jquery', '1.3' %>
    <%= google_load_tag 'jqueryui', '1.7' %>
    <%= javascript_include_tag 'application' %>
    <%= yield :head %>
    <%- javascript_tag do -%>
      jQuery(function($){
        if (navigator.cookieEnabled) {
          $("#cookie_check").hide();
        } else {
          $("#cookie_check").show();
        }
        <%= yield :script %>
      });
    <%- end -%>
    <%= stylesheet_link_tag 'application' %>
    <%= stylesheet_link_tag 'jquery-ui-1.7.2.custom' %>
    <title><%= @title %></title>
  </head>
  <body>
    <!-- 略 -->
  </body>
</html>

こうしておくと view では以下のように書くことができる。

<%- content_for :script do -%>
$("a#hoge").click(function(event){ /* なんか処理 */});
<%- end -%>

global な名前空間を汚さないし、割と短く書けるし気に入っている。

Posted in ,  | タグ , , ,  | コメントはありません | トラックバックはありません

prawn with Rails2.3.5

公開日時 okkez Fri, 12 Feb 2010 04:00:00 GMT

prawn を Rails2.3.5 で使おうと思って調べてみたら、prawnto が使えなくなっていた。

仕方が無いので prawn 単体を Rails で使う方法を考えてみたので書いておく。

以下のコードをそれぞれのファイルに書く。

# config/environment.rb
config.gem "prawn"
config.gem "prawn-layout", :lib => "prawn/layout"
config.gem "prawn-security", :lib => "prawn/security"

config.gem “prawn” だけだと prawn/{layout,security} がちゃんと読み込まれないので別の場所で require する必要がある。

# config/initializers/mime_types.rb
Mime::Type.register "application/pdf", :pdf
# 適当なヘルパー
  def render_pdf
    pdf = Prawn::Document.new(:page_size => "A4")
    # フォントは環境に合わせる
    pdf.font "/usr/share/fonts/truetype/vlgothic/VL-Gothic-Regular.ttf"
    yield pdf
    pdf.render
  end

以上を追加したら、割と簡単に PDF を出力することができるようになる。

コントローラーでこんな風に書いて、

class ReportsController < ApplicationController
  def show
    @report = Report.find(params[:id]
    respond_to do |format|
      format.html # show.html.erb
      format.pdf # show.pdf.erb
    end
  end
end

ビューでこう書けばよい。

# show.pdf.erb
<%=
render_pdf do |pdf|
  pdf.text "Hello, PDF world!"
end
%>

追記

本家(github)をよく見たら別の方法が書いてあった。 * Using Prawn in Rails - prawn - GitHub

どっちが良い方法なんだろう。 github に書いてある方法だとちゃんとダウンロードするファイル名を指定できるのが良い。

自分が書いた方法だと、view なので view で使用するデータの受け渡しが楽だけどファイル名の指定とかが面倒。 あと Emacs で適切なモードになってくれないのが気にくわない。

Posted in  | タグ ,  | 2 comments | トラックバックはありません

そろそろるりまを使ってみませんか?

公開日時 okkez Fri, 18 Dec 2009 13:32:00 GMT

この記事は Ruby Advent Calendar jp: 2009 : ATND の 18 日目です。前日は @tad さん でした。

愛用しているものの一つに るりま があります。 みなさんはもうお使いですか?

まだの人は以下の説明を読んでぜひ使ってみてください。

利用方法はいくつかあるので順番に紹介していきます。

web ブラウザを使って見る方法

http://doc.okkez.net/ にアクセスします。3 カラムになっていて左から順番に、BitClust, Static HTML, Download となっています。BitClust はるりまプロジェクトで作ったリファレンスマニュアルを見るためのウェブアプリケーションです。 doc.okkez.net では nginx + thin で動かしています。nginx がキャッシュするようにしているのでまあまあの速さで動くと思います。

Static HTML はあらかじめプログラムで生成した HTML ファイルを置いています。ウェブアプリケーション版とは少しレイアウトが異なりますが内容は同じです。参照したいクラスやメソッドが既に決まっている場合に使うと高速に参照することができます。ウェブブラウザのページ内検索機能を使用すると快適に閲覧できるでしょう。

Download は月一回肉の日(毎月29日)に作成したスナップショットを置いています。http://www.ruby-lang.org/ja/man/archive/ にも同じものを置かせていただいています。

ダウンロードしたアーカイブを使用する方法

  • http://www.ruby-lang.org/ja/man/archive/
  • http://doc.okkez.net/archives/

どちらかから、ダウンロードしたアーカイブを適当な場所に展開します。 アーカイブの中には以下のようなものがあります。

  • bitclust/ ライブラリ
  • db-1_8_7/ Ruby1.8.7 向けのデータベース
  • db-1_9_1/ Ruby1.9.1 向けのデータベース
  • readme.html このアーカイブの説明
  • refe-1_8_7 Ruby1.8.7向けの refe
  • refe-1_8_7.cmd Windows 用の Ruby1.8.7 向けの refe
  • refe-1_9_1 Ruby1.9.1 向けの refe
  • refe-1_9_1.cmd Windows 用の Ruby1.9.1 向けの refe
  • server.exe Windows 用の実行ファイル
  • server.exy server.exe を作るための exerb のレシピファイル
  • server.rb *nix などで使用するスクリプト

データベースというのは、指定したバージョン向けに前処理を施したテキストファイル群のことです。

このディレクトリにパスを通して使うのが一番簡単ですが、適当なスクリプトを書いたりするのもいいでしょう。例えば、以下のような感じで書くといいのではないでしょうか。

#! /bin/sh
DOC_BASE=$HOME/ruby-refm
exec ruby -Ke -I $DOC_BASE/bitclust/lib bitclust/bin/refe.rb -d $DOC_BASE/db-1_8_7 "$@"

Windows な人は *.cmd を参考にしてバッチファイルを書くといいのではないでしょうか。

また server.exe というファイルがありますが、Windows を使っている人はこれをダブルクリックすると、ローカルで web server が起動して、自動的にウェブブラウザが起動してリファレンスマニュアルを表示します。ローカルで動いているのでネットワークにつながっていないときでも使用できます。

ダウンロードした chm ファイルを使う方法

  • http://www.ruby-lang.org/ja/man/archive/
  • http://doc.okkez.net/archives/

先ほどと同様に、ダウンロードします。 chm はバージョン別になっているので自分が使いたい方をダウンロードすればいいでしょう。1.8.7, 1.9.1 以外のバージョンを使いたい人は、自分で chm ファイルを作るといいでしょう。(ここでは説明しません)

Windows Vista 以降の人は、ダウンロードしたファイルをダブルクリックしたときに出てくる警告ダイアログのチェックボックスを外すとちゃんと見られるはずです。

Windows を使っていない人はそれぞれ自分の好きな chm viewer をインストールして使ってください。意外と色々あります。

まとめ

個人的におすすめなのはコマンドラインから使用する refe です。すごく速いです。 とりあえず使ってみてください。古いリファレンスには書いていないこともたくさん書いてあります。 足りない部分はありますが、古いリファレンスよりはかなり進化しています。使わないと損です。 そして、使ってフィードバックをください。みなさんのご協力をお待ちしています。

明日は、たこ焼き仮面の中の人ではないかと噂されているあの人が書きます!

Posted in  | タグ ,  | コメントはありません | トラックバックはありません

Rails の generator gem のテスト方法

公開日時 okkez Fri, 18 Dec 2009 14:39:00 GMT

自分で Rails の generator gem のテストを書いてみたんだけど、どうもしっくり来ない。

参考にしたのはここ。

作ってた engines はこれ。

やりたかったことは以下のとおり。

  • Rails Engines なので基本的には Rails アプリケーションとしてテストしたい
  • generator は engines として使うときに必要なファイルを生成するためのものなので独立してテストしたい
  • rake test でちゃんとテスト出来れば OK

で、冒頭の Rails Guides を参考にテストを書いてみたけどちゃんと動かなかったので Rails のソースを読んでみた。 読んでみて分かったのは以下のこと。

  • Rails::Generator::Scripts::Generate#run でファイルを生成する先は指定できる
  • けど、generator をどこから探してくるかは指定できない
  • RAILS_ROOT が定義されていると RAILS_ROOT/lib/generators や RAILS_ROOT/vendor/generators などから探してくれる
  • 他には既にインストール済みの generator からも探してくれる
  • RAILS_ROOT/generators は見てくれない

作っているのは engines gem なのだから RAILS_ROOT/generators も見てほしいんだけど、それはやってないらしいので、ここでは RAILS_ROOT/lib/generators に symlink を張ることにした。 一応、これでちゃんと動いているみたいなのだけど、setup で symlink 作成して teardown で symlink を削除したりしてるのがちょっと気持ち悪い。

Rails Guides にも書いてあったとおり generator を提供している多くの Gem は generator 自体のテストは書いていない。(cucumber や rspec を参考にしたかったんだけど書いてなかった。)

もう一回やりたかったことをまとめるとこうなる。

  • Rails Engines なので基本的には Rails アプリケーションとしてテストしたい
  • generator は engines として使うときに必要なファイルを生成するためのものなので独立してテストしたい
  • 既存の generator を読み込まずにテストしたい (開発中の Gem と同名の Gem が入っていてもいいように)
  • rake test でちゃんとテスト出来れば OK

あ、コードは github に全部上がっているので見てください。

みんな generator のテストはあんまり書かないものなのかなぁ?

Posted in ,  | タグ ,  | コメントはありません | トラックバックはありません

Hikifarm on Rack

公開日時 okkez Wed, 25 Nov 2009 12:48:00 GMT

Hikifarm on Rack の対応をしてみました。

  • https://svn.sourceforge.jp/svnroot/hiki/hiki/branches/rack

やっと Hikifarm on Rack を実装出来たので rack ブランチにコミットしてみました。 まだ足りない部分はいくつかありますが、余裕のある人は試してみてください。 コードやファイル名についてもコメントをください。

使い方

  • misc/hikifarm/hikifarm_conf.rb を Hiki のインストールディレクトリにコピーする
  • hikifarm_conf.rb を環境に応じて書き換える
  • 必要っぽいディレクトリを作成しておく
  • 以下のコマンドを実行する
 $ rackup hikifarm.ru

注意

  • Hikifarm, Hiki ともにデフォルトで UTF-8 で動作します
  • 古い misc/hikifarm/index.cgi は変更してませんが使えないと思います

主な変更点

  • misc/hikifarm/index.cgi から hiki/farm.rb, hiki/farm/{config,dispatcher,manager,page,wiki}.rb に分離
  • Hikifarm の内部的にコードを整理した
  • Hiki::Config.new に hikiconf.rb のパスを指定できるようにした
  • UTF-8 化

TODO (把握してるものだけ)

  • Hikifarm の RSS 出力
  • 複数の wiki を作成したときの動作確認
  • attach の動作確認を行う
  • テストを書く
  • リファクタリング

Posted in ,  | タグ ,  | コメントはありません | トラックバックはありません

Rails Engines なプラグインを書いてみた

公開日時 okkez Fri, 18 Dec 2009 14:38:00 GMT

Rails Engines なプラグインを書いてみたら、いくつかハマったポイントがあったので未来の自分のために記録しておく。

  1. スタイルシートや画像などが読めない
  2. マイグレーションファイルをどうしよう
  3. プラグインがロードできない
  4. Engine 側で使っている Gem を rake gems などで扱いたい

大体この四つくらいかと。それ以外は普通にアプリケーションを作れば OK

スタイルシートや画像などが読めない

これは簡単で、本家でも解説されてた。 Rake タスクを作ってコピーするだけ。

マイグレーションファイルをどうしよう

これも簡単。本家では、プラグイン側のマイグレーションを実行する方法がまだ無いから仕方ないと書かれていた。 Rake タスクを作ってコピーすればいい。タイムスタンプなマイグレーションを使っている場合はこれで問題ないはず。

プラグインがロードできない

これは調べるのに時間がかかったけど分かってみれば簡単だった。 plugin_root/init.rb や plugin_root/rails/init.rb では Rails::Initializer.run のブロックパラメータの config が見える ので(正確には違うけど)それ経由で以下のようにしておくとよいみたい。

plugin_root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
config.plugin_paths << File.join(plugin_root, 'vendor/plugins')

Engine 側で使っている Gem を rake gems などで扱いたい

プラグインと同様、init.rb 内で config.gem すれば良い。

Posted in ,  | タグ ,  | コメントはありません | トラックバックはありません

annotate_models_with_index

公開日時 okkez Wed, 04 Nov 2009 15:14:00 GMT

annotate_modelsにindexの情報を付加する - Hello, world! - s21g

こちらで公開されてたものに少し気になるところがあったので修正してみたのが以下。

okkez’s annotate_models_with_index at master - GitHub

修正ポイントは

  • trailing spaces を書き込まないようにした
  • magic comment を保存するようにした

です。

よかったら使ってみてください。

Posted in  | タグ ,  | コメントはありません | トラックバックはありません

Rails2.1.2 -> Rails2.3.2 で変わったこと

公開日時 okkez Mon, 06 Jul 2009 15:09:00 GMT

いろいろなところで出尽くしている感はありますが、それらでは触れられていないであろう事をいくつか書こうと思います。

delegate で private メソッドを呼べなくなった

2.1.2 では呼べていたのですが、呼べなくなりました。 これは send が可視性をチェックしていないためです。 ActiveRecorde::Associations::AssociationProxy#method_missing でのチェックが厳しくなっています。

gettext_activerecord になった

gettext が gettext_activerecord などに分割されました。 このことにより human_name_without_gettext -> human_name_without_gettext_activerecord などのように する必要がありました。

もう少し書くことがあった気がしたのだけど、二つしかなかったorz

でも一番驚いたのは、Rails のソースをスラスラ読んでる自分に今、気がついたことです。

Posted in  | タグ ,  | コメントはありません | トラックバックはありません

Rabbit のテーマを作る方法

公開日時 okkez Thu, 25 Jun 2009 08:08:00 GMT

Rabbit のテーマを作る方法を調べてみた。自分のテーマを試行錯誤して作っている途中なのでツッコミ歓迎。

基本的なことは README.ja にも書いてある。

既に存在しているテーマの色違いのテーマを作るのは簡単で、置き場所に適当な名前でファイルを作成して以下のようにすれば良い。

# include_theme の前にカスタマイズしたい色の設定を記述する
@block_quote_frame_width  = 1
@block_quote_fill_color   = "#eeeeee" # 引用の色を変える
include_theme("foo")

この場合は include_theme しているテーマが他のテーマを include_theme している場合が多いのでそれらを順番に辿っていくと好みの色に設定することができると思う。大抵の場合は default-* を参照してそれっぽいインスタンス変数を探すといいです。

参考になるテーマがあるけど、デザインが違う場合はちょっとだけ難しい。 しかし、まだなんとかなるレベル。

参考にするテーマから該当するブロックを自分のテーマファイルにコピペして編集するのが手っ取り早い。 試行錯誤が必要ですが、何回も繰り返せばなんとか目的のものを作ることができると思う。

フルスクラッチで作る場合というのは実はそんなになくて、ほとんどの場合は参考になるテーマから色々といただいてくればやりたいことはできるはず。

# 色などのカスタマイズ
include_theme("default")
# 以降にその他のカスタマイズ

上のような感じでやれば、そこそこ見られるテーマができると思う。

このへん を参照して参考にするテーマを探すと早いかもしれない。

一応、今回作ったテーマ (未完成) 。

@block_quote_frame_width  = 1
@block_quote_fill_color   = "#eeeeee"

# FIXME
@default_item1_mark_color = "#000000"
@default_item2_mark_color = "#333333"
@default_item3_mark_color = "#666666"
@default_enum_item1_mark_color = "#333333"
@default_enum_item2_mark_color = "#666666"
@default_description_item1_mark_color = "#ff9933"
@default_block_quote_item1_mark_color = "#ff9933"

@description_term_line_color = "#3333aa"

@preformatted_frame_width = 1
@preformatted_fill_color  = "#eeeeee"

@table_frame_width     = 1
@table_caption_color   = "#000000"
@table_head_fill_color = "#dddddd"
@table_fill_color      = "#eeeeee"
include_theme("default")

set_foreground("black")
set_background("white")

match(Slide, HeadLine) do |heads|
  name = "head-line"

  heads.delete_post_draw_proc_by_name(name)

  heads.horizontal_centering = false
  heads.prop_set("foreground", "white")

  x_space = screen_x(2)
  y_space = screen_y(1)

  heads.padding_top    = y_space * 2
  heads.padding_bottom = y_space * 2

  color = "#3333aa"

  heads.each do |head|
    pre_y = nil
    width = nil
    height = nil
    head.add_pre_draw_proc(name) do |canvas, x, y, w, h, simulation|
      pre_y = y
      unless simulation
        border_x = x - x_space * 2
        border_y = y - y_space * 2
        border_width = width + x_space * 4
        border_height = height + y_space * 4
        canvas.draw_rectangle(true, border_x, border_y,
                              border_width, border_height, color)
      end
      [x, y, w, h]
    end
    head.add_post_draw_proc(name) do |canvas, x, y, w, h, simulation|
      width = w
      height = y - pre_y
      [x, y, w, h]
    end
  end
end

たぶん、これ以上凝ったものを作ろうと思ったらソースを真面目に読まないといけない気がする。

Posted in ,  | タグ ,  | 2 comments | トラックバックはありません

vlad 使ってみた

公開日時 okkez Sun, 03 May 2009 04:04:00 GMT

Vlad the Deployer を使ってみた。

Rails アプリケーションのデプロイツールを Capistrano から vlad に移行してみたら簡単だったけどメモっておくことにする。 ほとんど vlad のドキュメントに書いてあるのだけど、一応。

インストール

  $ sudo gem install vlad

で OK.

セットアップ

Rakefile に以下のように記述する。

begin
  require 'vlad'
  Vlad.load :app => :thin, :web => :nginx
rescue LoadError
  # nothing to do
end

また RAILS_ROOT/config/deploy.rb を用意する。

set :application, "application name"
set :domain, 'example.com'
set :repository,  "file:///path/to/repository"
set :deploy_to, "/path/to/#{application}"

これだけで完了。

SSH を使う

SSH を使ってリモートデプロイする場合は ~/.ssh/config を編集する必要があるかもしれない。 うちの場合はデフォルトの秘密鍵をデプロイ先のサーバに登録してあるので必要なかった。

パスフレーズを入力するのが面倒な人は ssh-agent とか keychain とか使うといいです。 Debian なら両方共パッケージが用意されているし。

さらにうちの場合は、リポジトリをデプロイ先のサーバに同居させているので ‘file://’ になるわです。 そうでない場合は svn で使えるパスの記述形式は全部通るはずなので、好きな様に書くといいと思います。

デプロイ

以下で OK です。 capistrano の時より簡単かもしれないです。 あと、 vlad:setup で thin の設定ファイルを生成してくれたのは地味に便利だった。

$ rake vlad:setup    # 最初の一回だけ
$ rake vlad:update  # 毎回 (デプロイ先で必要なファイルを SCM 経由で取得する)
$ rake vlad:migrate # 毎回 (デプロイ先で rake db:migrate する)
$ rake vlad:start    # 毎回 (app, web を restart する)

nginx まで再起動しないで欲しい

バカ正直に vlad に web server は nginx ですって教えてあげたら rake vlad:start で nginx まで再起動されて迷惑だった。 いくら nginx が再起動早くても一つのサービスをデプロイするのに複数のサービスを止めたら意味ないので、何もしないようにするにはどうすればいいか調べてみた。

ソースを読んだら :web => nil でいけそうだったけど、エラーが発生して無理だったので 何もしないタスクを作って以下の様に Rakefile を修正した。 特に passenger や thin を使っている人には必要だと思うのだけど、どうなんでしょう。

begin
  require 'vlad'
  Vlad.load :app => :thin, :web => :nothing
rescue LoadError
  # nothing to do
end

んで、 vlad/nginx.rb のあるディレクトリに vlad/nothing.rb をコピーして中身を編集したら予想通り nginx の再起動は実行されなくなりました。

Vlad.load のオプションを使えば色々なことが出来そうです。 デフォルトが、結構充実しているのですが、いらんこともしてくれる vlad なのでした。 しかし、そのデフォルトの挙動を簡単に変えられるのであまり困りませんでした。

ただ、デフォルトで何もしないターゲットを読み込むファイルは各オプションにあってもいいのかなぁとか思いました。

追記

やっぱり :web => nil で OK だった。

:web => nil だと vlad:start などが定義されないようだ。 なので、そのときは rake vlad:start_app を実行する必要がある、と。

:web => nil でも vlad:start は定義されて欲しいなぁ。

Posted in  | タグ , ,  | コメントはありません | トラックバックはありません