リレーションを持ったARオブジェクトをセッションにいれる場合の問題(Rails2.x ?)

リレーションを持ったARのオブジェクトをセッションに入れる場合の問題についてです。

たとえば、

 Item -> Category
                                • -
items name:string category:references categories name:string

のようなDBがあったとして、itemに belongs_to :category と定義しておく。

itemの作成ページ(newアクション)とcreateアクションの間に確認画面を挟むために、セッションを使い次のようなコードを書いた場合、@itemのCategoryのオブジェクト(@item.category)が変更できなくなってしまいました。

# items_controller.rb
def new
  session[:item] = @item = session[:item] || Item.new
end
def confirm
  @item = session[:item]
  @item.attributes = params[:item]
end
def create
  @item = session[:item]
  @item.save!
  redirect_to @item
end

確認画面にitemのcategoryを表示する場合、最初の表示では変更が反映されるが、2度目以降は反映されなくなります。
@item.category_idを直接変更しても、@item.categoryは変更されませんでした。
@item.category.idとすると最初に選らんだcategoryのidになります。

想像ですが、どうやら sessionに入れることで、キャッシュのコントロールがおかしくなってしまうのではないかと思います。

対策としては、

@item.attributes = params[:item]
@item.category.reload

というように、@item.category_idを更新した後に、@item.categoryをreloadしてやることで値が読みなおされ正常に動作するようになりました。

1.2.x系ではならなかった(と思う)ので、ついハマってしましました・・・・


というか、確認画面ってどういう風に実装するのがいいんでしょうね。
セッションを使うとセッションを削除するタイミングが難しいし、かといってflashじゃ想定外のページ遷移で消えちゃうし、hidden渡しはコードが面倒になるし。


まぁ、どこかの記事で海外では確認画面なんてナンセンスだと思われているというのをみた気もしますが・・・
入力した内容を確認しない人は、確認画面があっても、結局確認とかしないという感じの理由。
海外のフリーソフトで確認画面がないのもがあるのもそのためだと言われれば納得できるような。