Excelですぐ開けるUnicodeなCSVをRubyで生成する

Excelで開ける、Unicode文字列を含むCSVファイルを生成する方法。Microsoft Excel for Mac 2011で開けることを確認した。

Excelで開けるUnicode文書を作るポイントは以下の2点。

UTF-16 LE with BOMで保存する
UTF-8は文字化けして、UTF-16 BEはフリーズした
タブ区切りで保存する
カンマを使う場合はテキストファイルウィザードを使わなければならない

続きを読む Excelですぐ開けるUnicodeなCSVをRubyで生成する

日本の高速道路の出入り口はいくつあるのか

ふと所用により、日本の高速道路の出入り口(インターチェンジ)の概算が知りたくなった。頭のいい人ならチャチャッとフェルミ推定して算出するのだろうが、考えるよりダーティコードを書いた方が早いと思ったので高速道路の出入口数を調べるテキトーなスクリプトを組んだ。Wikipediaには「日本のインターチェンジ一覧」というページがあるので、そこから情報を引っ張ってきて日本の高速道路のインターチェンジの数をざっくり算出する。

実行したら、2,692ヶ所と出た。2013年10月11日現在、最低でも日本に2,692カ所は高速道路の出入り口があるっぽい。

以下、概算に使ったコード。ハードコーディングしまくりなので、Wikipediaのページの構成が変わったらすぐに使えなくなるので要注意。

railsでsanitizeすると閉じタグを付け忘れた時にタグが続いてしまう

sanitizeというメソッドを使うと、ホワイトリストに載ったHTMLタグ以外を削除して出力できる。例えば以下のようなコード(haml)を書くと、

%p
  - dummy_text = '斜め'
  = raw(sanitize(dummy_text))
斜め

と出力される。

通常はこれで問題ないが、タグが閉じられないままだと、続けて出力されてしまう。

%p
  - dummy_texts = ['<i>斜め' '斜めったまま']
  - dummy_texts.each do |dummy_text|
    %p
      = raw(sanitize(dummy_text))

↓こんな感じ。

斜め
斜めったまま

つまり、validではないHTMLをvalidにするにはどうすればいいかという問題。

続きを読む railsでsanitizeすると閉じタグを付け忘れた時にタグが続いてしまう

Mongoidのany_ofがorではなくandになる

any_ofでorの結果を取得したいのに、結果はandになってしまう、という場合

User.any_of(:created_at.gte => 1.week.ago, :name => /^j/)

上記のコードは、1つのハッシュをany_ofとして渡している。any_ofはハッシュを複数渡すのが正解なので、以下のコードが正しい。

User.any_of({:created_at.gte => 1.week.ago}, {:name => /^j/})

よくミスするのでメモ。

Rails + HAMLの環境で、URL Helperを使いながらjQuery Templateを使う

JavaScirptで利用できるテンプレートエンジンに「jQuery Templates」がある。これにはjquery-tmpl-railsというgemも用意されていて、すぐに使い始めることができる。使い方のチュートリアルとしてはブログ記事”jQuery公式のテンプレートplugin 「jQuery Templates」-JavaScript Library Archive“が分かりやすい。

railsのurl helperを使うと、routes.rbに書かれた内容に沿ってURLを自動で生成してくれる。例えば、routes.rbにresource :booksと書いていた場合、指定のIDのBookのページのURLを取得するにはbook_path(:id)と書けばよい。詳しくは以下参照。
2.3 Paths and URLs – Ruby on Rails Guides: Rails Routing from the Outside In
この時、:idに相当する部分は自動でURLエンコードされる。ここをjQuery Templatesで書き換えたい場合、ダラー( $ )と波括弧( { と } )がエスケープされてしまう。それを避ける方法。

あまり綺麗な書き方ができなかったので、もっとベターな方法(例えばURLHelperの機能を使う時にURLエンコードを禁止するような方法)があったらどなたか教えてください。

Mongoidでcallback(before_save等)を呼ばずにupdateする

before_save, after_saveといったコールバックを実行せずにフィールドの値を更新するには、setメソッドを利用する。after_saveの中で値を更新したい時に便利。
以下は例。

item = Item.first
item.set(:description, "It's so nice!")

簡単ですね。

http://mongoid.org/en/mongoid/docs/persistence.html#atomic

ActiveRecordでcallbackを呼ばずにupdateする

ActiveRecord::Baseを継承したクラスの中で、before_save, after_saveなどを書くと、保存前や保存後に呼び出されるメソッドを指定できる。しかし、これらのコールバックの中で例えばsaveメソッドを実行してしまうと、stack level too deep (SystemStackError)というようなエラーが起きてしまう。

参考にしたのは以下のページ:
ruby on rails – Skipping callbacks and validation – Stack Overflow

以下のドキュメントにリストアップされているメソッドは、こういったコールバックを呼び出さずにスキップして、updateをかけることができる。
http://guides.rubyonrails.org/active_record_validations_callbacks.html#skipping-callbacks

続きを読む ActiveRecordでcallbackを呼ばずにupdateする

I18n.tで変数を使う/動的に翻訳を増やす

I18n.tを使ってyamlから文字列を読み込んでいる時、文中に変数名を入れたいことがある。その場合は、yaml側では変数名を%{ }と囲んで、I18n.tの引数としてハッシュを渡せばよい。詳しくは、以下のドキュメントに記載されていた。

http://guides.rubyonrails.org/i18n.html#interpolation

上記URLからサンプルコードを引用:

I18n.backend.store_translations :en, :thanks => 'Thanks %{name}!'
I18n.translate :thanks, :name => 'Jeremy'
# => 'Thanks Jeremy!'