February 17, 2009

Rails2.3 の Nested Attributes を試す

Rails2.3 の Nested Attributes の機能を試してみました。

rails 2.3 のインストール

rails 2.3 は以下のようにしてインストールしました。

sudo gem install rails --source http://gems.rubyonrails.org

アプリケーションの作成

アプリケーションを作り、モデルをいくつか作成します。

% rails nested_attributes_sample
% cd nested_attributes_sample
% script/generate model book title:string
% script/generate model author name:string book_id:integer
% script/generate model page text:text book_id:integer
% rake db:migrate

モデルファイルに関連の情報を書きます。

app/models/book.rb

class Book < ActiveRecord::Base
  has_one :author
  has_many :pages

  accepts_nested_attributes_for :author
  accepts_nested_attributes_for :pages, :allow_destroy => true
end

accepts_nested_attributes_for メソッドを呼び出しているところがポイントです。
これにより authorpages に対して Nested Attributes の機能が使えるようになります。
さらに pages に関しては :allow_destroy => true とすることで親(Book)から削除できるようにしています。

app/models/author.rb

class Author < ActiveRecord::Base
  belongs_to :book
end

app/models/page.rb

class Page < ActiveRecord::Base
  belongs_to :book
end

確認

script/console でちゃんと動作するか確認してみます。

% script/console

One-to-one

まずはデータの作成。

>> book = Book.create({:title => 'ruby book', :author_attributes => {:name => 'foo'}})
>> book.author.name
=> "foo"

ちゃんと book.author が作成されてますね!

次にデータの更新。

>> book.update_attributes({:author_attributes => {:name => 'jugyo'}})
>> book.author.name
=> "jugyo"

ちゃんと更新されてますね!

One-to-many

次は「一対多」の場合のデータ作成のやり方です。
こんなふうにします。

>> book = Book.create({
              :title => 'rails book',
              :pages_attributes => {
                'new_1' => {:text => 'aaaaaaaaa'},
                'new_2' => {:text => 'bbbbbbbbb'},
                'new_3' => {:text => 'ccccccccc'},
              }
       })
>> book.pages.size
=> 3
>> book.pages[0].text
=> "aaaaaaaaa"

おお、ちゃんとできてるっぽい!
page に対応する 各 Hash のキーは 'new' という文字列から始まっている必要があるようです。

データを更新してみます。

>> book.attributes = {:pages_attributes => {1 => {:text => 'AAAAAAA'}}}
>> book.pages[0].text
=> "AAAAAAA"

データを削除してみます。

>> book.attributes = {:pages_attributes => {1 => {'_delete' => '1'}}}
>> book.save
>> book.pages.size
=> 3

ん?、book.pages.size が 3 のままですね。
でも DB を見てみるとちゃんと削除されてたのでとりあえずはよしとします。

参考URL:
http://weblog.rubyonrails.org/2009/1/26/nested-model-forms
http://api.rubyonrails.com/classes/ActiveRecord/NestedAttributes/ClassMethods.html

No Comments »

TrackBack URI

Leave a comment

※上の項目は入力してもしなくてもよいです。