soraなりの日々 - fc2 -

こころにひっかかったもの

[ruby19, rails23] accepts_nested_attributes_for について理解する

なんだか技術系を書くのが久しぶりな気がする。。。
rails 2.3 もリリースされたことだしね、ってことで、
次の業務で使用すべく、ruby 1.9rails 2.3 の環境を
ubuntu で作ってちょっと遊んでみた。

今回、rails 2.3 で入った accepts_nested_attributes_for
使ってみたのでまとめてみる。

前記事。
[[ruby, rails]今更だが、has_many :through(多対多)をまとめてみよーか]
http://sora2hs.blog70.fc2.com/blog-entry-394.html

[[ruby, rails] :polymorphic について理解する]
http://sora2hs.blog70.fc2.com/blog-entry-418.html

このエントリーをはてなブックマークに追加
rails 2.3 のリリースノートは
うぇぶたまさんところを参考に。

[Rails2.3リリースノート訳]
http://webtama.jp/series/railstips/articles/31

相も変わらず、いっぱい機能追加されてますね、と。
しかも、今回は ruby 1.9 にも対応ってことで
上に乗っかって開発やってるものとしては、覚えることが山ほど・・・orz

が、がんばっていきましょう!

んで、今回は "accepts_nested_attributes_for"
(名前長過ぎ。。。)

子テーブルのデータを親テーブルから直接更新できるってやつ。
名前は長いがコレは便利だぞっと!

では、説明を。

[railroad で吐き出した er 図]
attributes_modes

Project ... プロジェクトテーブル
Member ... メンバーテーブル
ProjectMember ... プロジェクト、メンバーを繋ぐ中間テーブル
ProjectMemo ... プロジェクトにメモするテーブル(プロジェクトの子テーブル)

そんで、モデルの設定。

[models/project.rb]
class Project < ActiveRecord::Base
  has_many :project_memos

  # has_many :through
  has_many :project_members, :dependent => :destroy
  has_many :members, :through => :project_members

  # nested attributes

  accepts_nested_attributes_for :project_memos
  accepts_nested_attributes_for :project_members
end

Member とは、前にも書いた has_many :throught
project.members でアクセスできるようにしている。

[models/member.rb]
class Member < ActiveRecord::Base
  # has_many :through
  has_many :project_members, :dependent => :destroy
  has_many :projects, :through => :project_members

  # nested attributes

  accepts_nested_attributes_for :project_members
end


Project とは、前にも書いた has_many :throught
member.projects でアクセスできるようにしている。

[models/project_member.rb]
class ProjectMember < ActiveRecord::Base
  belongs_to :project
  belongs_to :member
end


[models/project_memo.rb]
class ProjectMemo < ActiveRecord::Base
  belongs_to :project
end


accepts_nested_attributes_for した各アクセサは xxx_attributes となる。
script/console で動作を確認してみる。

$ script/console
>> proj = Project.new
=> #<Project id: nil, name: nil, created_at: nil, updated_at: nil>
>> proj.members  # 当然空っぽ
=> []
>> proj.project_members_attributes = {"new" => {:member_id => 2}}  # 新しく子に追加
=> {"new"=>{:member_id=>2}}
>> proj.save  # 親を save
=> true
>> proj.members  # まだ空っぽ
=> []
>> proj.reload  # リロードする
=> #<Project id: 6, name: nil, created_at: "2009-03-18 14:56:54", updated_at: "2009-03-18 14:56:54">
>> proj.members  # 追加されている
=> [#<Member id: 2, name: "bar", age: 12, created_at: "2009-03-18 06:17:39", updated_at: "2009-03-18 06:17:39">]

おおぉっ!
次、ビューで nested model forms を使う。

[views/projects/edit.html.erb]
<% form_for(@project) do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </p>

  <%# nested model forms %>
  <% f.fields_for :project_memos do |memo| %>
    <p>
      <%= memo.label :remark, 'remark:' %><br />
      <%= memo.text_field :remark %>
    </p>
  <% end %>

  <%# nested model forms %>
  <% f.fields_for :project_members do |member| %>
    <p>
      <%= member.label :member, 'member:' %><br />
      <%= member.select(:member_id, Member.find(:all).map{|u| [u.name, u.id]}) %>
    </p>
  <% end %>

  <p>
    <%= f.submit 'Update' %>
  </p>
<% end %>


[views/members/edit.html.erb]
<% form_for(@member) do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </p>
  <p>
    <%= f.label :age %><br />
    <%= f.text_field :age %>
  </p>

 
<%# nested model forms %>
  <% f.fields_for :project_members do |project| %>
    <p>
      <%= project.label :project, '
project:' %><br />
      <%= project.select(:project_id, Project.find(:all).map{|u| [u.name, u.id]}) %>
    </p>
  <% end %>

  <p>
    <%= f.submit 'Update' %>
  </p>
<% end %>


そんで、実際の画面。

[projects]
attributes_project
[members]
attributes_member
 

それぞれ、入力して更新すると自動で
子も更新される。

いやー、便利!

いままで、作成時、更新時にそれぞれコードを
書いてたのがこれで書かなくて済むわー。
わーい(^^;

名前が長過ぎるのがなんとも、、、だけど、
そこは alias でも切ってさ。。。

このエントリーをはてなブックマークに追加

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバックURLはこちら
http://sora2hs.blog70.fc2.com/tb.php/438-837effb0
この記事にトラックバックする(FC2ブログユーザー)

[Rails]RailRoadでRailsのソースからER図を作成する

soraさんが http://sora2hs.blog70.fc2.com/blog-entry-438.html で Rails2.3の新機能を紹介していますが、その中で[railroad で吐き出した er 図]と言うのが出てきています。RailRoadというのをつかうとRailsのソースからER図を作成できるらしい。 ”RailRoad”で検索してみ

  • 2009/03/19(木) 11:18:50 |
  • 橋本幸樹のいまさら日記