2008年11月10日 星期一

Handle Multiple Models in One Form Handle Multiple Models in One Form

http://www.pragprog.com/titles/fr_arr/advanced-rails-recipes
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#M001198

Recipe 13

[View, edit.rhtml]
<% form_for(@user) do |f| %>
<%= f.text_field :name %>
<% for book in @user.books %>
<% fields_for "user[books][]", book do |b| %> <= 用fields_for的方法注意
<%= b.text_field :name %>
<% end %>
<% end %>
<%= f.submit "Update" %>
<% end %>

[user controller, update action]
def update
@user = User.find(params[:id])

if @user.update_attributes(params[:user])
flash[:notice] = 'User and books was successfully updated.'
redirect_to(@user)
end

params[:user] 是長像這樣的東西 {"name" => "ilake",
"books" => {"1"=>{"name"=>"book1"}, "2"=>{"name"=>"book2"}}}
update_attributes 就是去做 @user.name = 'ilake'
@user.books = {"1"=>{"name"=>"book1"}, "2"=>{"name"=>"book2"}} 的動作
end

[user model]
class User < ActiveRecord::Base
has_many :books, :dependent => :destroy
has_one :couple
validates_presence_of :name

after_update :save_books

def books=(books_attrs) <= 因為controller 的@user.update_attributes 被叫到
books.reject(&:new_record?).each do |book| <= 檢查這是不是新的record, 這邊是update 新的不要
attributes = books_attrs[book.id.to_s]
if attributes
book.attributes = attributes
else
books.delete(book)
end
end
end

def save_books
books.each do |book|
book.save(false) # Calling save(false) saves the model without running validations.
end
end
end

沒有留言: