公開日時 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 Ruby, 雑記 | タグ javascript, jquery, Rails, Ruby | コメントはありません | トラックバックはありません
公開日時 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 Ruby | タグ Rails, Ruby | 2 comments | トラックバックはありません
公開日時 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 Programming, Ruby | タグ Rails, Ruby | コメントはありません | トラックバックはありません
公開日時 okkez
Fri, 18 Dec 2009 14:38:00 GMT
Rails Engines なプラグインを書いてみたら、いくつかハマったポイントがあったので未来の自分のために記録しておく。
- スタイルシートや画像などが読めない
- マイグレーションファイルをどうしよう
- プラグインがロードできない
- 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 Programming, Ruby | タグ Rails, Ruby | コメントはありません | トラックバックはありません
公開日時 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 Ruby | タグ Rails, Ruby | コメントはありません | トラックバックはありません
公開日時 okkez
Wed, 26 Aug 2009 12:45:00 GMT
ほとんど以下に書いてあるけど、最近 fixtures の整理をしてるので書いてみる。
- http://railsapi.com/doc/rails-v2.3.3.1/files/activerecord/lib/active_record/fixtures_rb.html
CSV とか single file とか色々あるけれどここでは YAML fixtures について書きます。
ラベルで参照する
pirates.yml
### in pirates.yml
reginald:
id: 1
name: Reginald the Pirate
monkey_id: 1
### in monkeys.yml
george:
id: 1
name: George the Monkey
pirate_id: 1
上記のようなものが以下のように書けます。
### in pirates.yml
reginald:
name: Reginald the Pirate
monkey: george
### in monkeys.yml
george:
name: George the Monkey
pirate: reginald
polymorphic belongs_to
今日一番の収穫がこれ。
### in fruit.rb
class Fruit < ActiveRecord::Base
belongs_to :eater, :polymorphic => true
end
### in fruits.yml
apple:
id: 1
name: apple
eater_id: 1
eater_type: Monkey
こんな風に書いていたのが、こう書けます。
### in fruits.yml
apple:
eater: george (Monkey)
今、修正している Rails アプリではポリモーフィック関連をたくさん使っているのでこれはすごく便利です。
belongs_to 応用
こんなモデル定義がある場合にはちょっと変わった書き方ができます。
# in expense.rb
class Expense < ActiveRecord::Base
has_many :expense_details
end
# in expense_detail.rb
class ExpenseDetail < ActiveRecord::Base
belongs_to :header, :class_name => 'Expense', :foreign_key => 'expense_id'
end
普通は belongs_to :expense と書きますが、上のように書くことで header と書けるようになります。
### expenses.yml
hawaii:
title: hawaii trip!
### expense_details.yml
chocorate:
name: chocorate
header: hawaii
nested set を使っているとき
nested set を使っている時はこう書けます。
### menus.yml
root:
name: root
parent_id:
menu_1:
name: menu_1
parent_id: <%= Fixtures.identify(:root) %>
$LABEL
$LABEL を使うと上の menus.yml がこうなります。
### menus.yml
root:
name: $LABEL
parent_id:
menu_1:
name: $LABEL
parent_id: <%= Fixtures.identify(:root) %>
他にもまだまだ便利な書き方はたくさんありそうです。
Posted in Programming, Ruby | タグ Rails | コメントはありません | トラックバックはありません
公開日時 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 Ruby | タグ Rails, Ruby | コメントはありません | トラックバックはありません
公開日時 okkez
Sun, 03 May 2009 04:04:00 GMT
Vlad the Deployer を使ってみた。
Rails アプリケーションのデプロイツールを Capistrano から vlad に移行してみたら簡単だったけどメモっておくことにする。
ほとんど 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 Ruby | タグ Rails, Ruby, vlad | コメントはありません | トラックバックはありません
公開日時 okkez
Tue, 03 Feb 2009 02:53:00 GMT
ちょっとひっかかったのでメモ。
jquery の treeview で動的にツリーを構築する場合は JSON 形式でデータを返さなければならない。
そんなときに使用する方法。
treeview の構築はこんな感じで。
jQuery("#ulid").treeview({
url: "<%= url_for(:controller => 'foo', :action => 'tree', :format => 'json') %>",
ajax: {
data:{"authenticity_token": token},
type: "post"
}
})
action はこんな感じ。ファイル名は tree.json.erb とかで。
# ...
def tree
# ... インスタンス変数とかの準備
@data = Item.find(:all, :select => 'id, name', :order => 'name')
respond_to do |format|
format.json
end
end
# ...
view はもっと複雑でもいいですがこんな感じで。
<%=
@data.map{|e|
{
:id => e.id,
:text => e.name,
:hasChildren => has_children?(e.id) # helper で実装する
}
}.to_json
%>
Posted in Programming, Ruby | タグ Rails | コメントはありません | トラックバックはありません
公開日時 okkez
Fri, 26 Sep 2008 13:19:00 GMT
コメントが有効になりました のコメントで指摘された件ですが、どうやら Typo のバグのようです。
RAILS_ROOT/config/routes.rb にあるルート定義を行っている方法が古いようです。
たぶん、名前付きのルートの部分を全面的に直さないといけない気がします。
とりあえず、上で指摘されていた部分は先頭(追加場所は未検証)
を追加すれば直りました。
本家にバグレポして直してもらう必要があるようです。
Posted in Ruby | タグ Rails | コメントはありません | トラックバックはありません