ひげろぐ

技術者として仕事人としての思うところや覚え書きやらです
Home      Profile      Works     
2009-09-09

Rails 2.3.4で追加されたseeds.rbについて

Seed Dataをマイグレーションから隔離するための仕組みが追加された。
これの一番の意図としては

「マイグレーションの中にデータをいじるコードを含めるのやめようぜ。な!」

ってことのようだ。

参考: http://github.com/rails/rails/commit/4932f7b38f72104819022abca0c952ba6f9888cb

Seed Dataって?

まあなんとなくニュアンスは分かるけど、そもそもSeed Dataって何なんだという疑問。

上記を参考にすると

  • ほとんど変更されないデータ
  • 例: Userテーブルの管理者アカウントのような初期データ
  • 例: アプリケーションの設定のためのデータ

ざっくり言うとアプリケーションの動作に必要な初期データ。
この中には都道府県マスタや権限マスタみたいなマスタも含めていいと思う。

db/seeds.rbの書き方

seeds.rbを開けば中に書いてあるサンプルコードですぐ分かるけど、単にseeds.rbにレコードを追加するコードを書いていくだけという単純な仕組みだ。

Category.create(:name => 'テント')
Category.create(:name => '寝袋')

とか

%w{テント 寝袋}.each do |name|
  Category.create(:name => name)
end

とかひたすらRubyのコードを好きなように書くべしとなっている。
フォーマットをCSVとかXMLとかYAMLとかに限定するでもなく、新しいDSLを定義するでもなく、好きなようにコードで書けよという投げっぱなしぶりが潔い。

まあもともとマイグレーション内にまざってたデータ作成/編集コードを分離させたものに過ぎないわけだね。

rake db:seed

seeds.rbの適用はrake db:seedという新しいタスクで行う。

又はrake db:setupを実行した際に読み込まれる。
ただrake db:setupはデータベースをイチから作り直すという破壊と創造を司るタスクなので稼働中の本番環境でうっかり使ったりしないように注意。

rake db:seedの挙動はきわめてシンプル

rake db:seedを叩くとseeds.rbの内容がその都度実行される。
この時既存のデータベースの内容は加味してくれず、今までに何回rake db:seedが実行されたのかなどの考慮もない。

つまりマスタデータを追加するつもりで

%w{テント 寝袋}.each do |name|
  Category.create(:name => name)
end

のようなコードを書いているとrake db:seedするたびにこれが何回も実行されてしまうので、ここらへんの面倒は自分で見ないといけないということだ。
例えば

Category.delete_all
%w{テント 寝袋}.each do |name|
  Category.create(:name => name)
end

みたいな。
ただこの例の場合はIDが変わってしまうのでIDを固定にしたければもうちょっと凝ったコードにしないといけない。

しかしながら実際のところseeds.rbにはあんまり複雑なコードは書かない方がいいだろう。
複雑になりそうならモデルにメソッドを実装してseeds.rb内では単純にそれを呼び出すだけとかにした方が幸せになれるはず。

rake db:seedするタイミングについて

rake db:seedは最初に一回だけ実行するべきものなんじゃないか?
という説も考えられるがそれだと運用途中でマスタを追加した時とか使えないし、結局マイグレーションファイルの中にデータ追加コードを書きたくなってしまう。
ので多分それは違うだろう。

マスタの初期化や再構築のトリガーとしてはちょうどいいので、アプリケーションを修正したときなど運用中の任意のタイミングで使いたい。
ということでseeds.rbはrake db:seedがいつ実行されてもデータに破綻が起きないように書いておいた方が良さそうだ。

まとめ

こうして見ると「便利な仕組み追加しました」というより「マイグレーションの中でデータいじるな」って言うスタンスを明確にしたいというのが一番の目的なかんじ。

  • データを作成/編集するコードはマイグレーションの中に書かない
  • データを作成/編集するコードはdb/seeds.rbに好きなようにRubyのコードで書く
  • rake db:seedで実行

seeds.rbのたぶんベターなプラクティス。

  • 複雑な処理はモデルに実装する
  • いつ実行されてもデータが破綻しないようにしておく
  • 何度実行されてもデータが破綻しないようにしておく
2009-09-04

ふたつの脆弱性に対処したRailsの2.2.3と2.3.4がリリース

本日リリース。
もうgemで入れられるようになってます。

主な内容はXSSとCookie storeに関する脆弱性の修正。
2.3.4では加えて100個ぐらいのバグ修正の他、いくつかの機能追加がされているようだ。

いつの間にか2.1系はセキュリティフィックスもなしっぽい。(リリースはないけどパッチは出ている)
自分も昔作ったやつは放置状態でまだ2.1のやつとかあるんだけど、そろそろ上げろってことかな。

XSS脆弱性

こちらはフォームヘルパーのバグによるXSS脆弱性。

対象は2.0.0以降のすべてのバージョン(ただしruby 1.9を使っている場合は影響なし)
修正済みバージョンは2.3.4、2.2.3。

Cookie storeの脆弱性

セッションストアにCookie storeを使っている場合、Cookieに含まれている値が改ざんされてないかどうかを検証するダイジェストを攻撃者が生成した任意のものにできる。
って書いてある気がする。
Cookie storeを使ってない人、そもそもセッションを使ってない人は慌てる必要なし。

対象は2.1.0以降のすべてのバージョン。
修正済みバージョンは2.3.4、2.2.3。

db/seeds.rbの追加

これは新機能。
各種マスタのデータとかをマイグレーションじゃなくてこれ使って入れなさいってことだと思う。たぶん。

よさげなのであとで使ってみよう。

2.0系と2.1系にはパッチ有り 2009/09/15追記

対応したバージョンのリリースはないけどパッチは出てたみたい。

InfoQ: Ruby on Railsのセキュリティの脆弱性

copyright brass.to | powered by WordPress ME