2010-06-18 98 views
4

嘿,我一直在用嵌套窗體的特殊用例(我使用Rails 2.3.5)對牆進行打我的頭。嵌套資源的Rails嵌套窗體:創建新has_many時更新belongs_to關聯

基本上我有項目和支付模式,看起來像這樣

class Project < ActiveRecord::Base 
    has_many :payments 
end 

class Payment < ActiveRecord::Base 
    belongs_to :project 
    accepts_nested_attributes_for :project 
end 

我還使用嵌套路由這兩個資源:

map.resources :projects do |project| 
    project.resources :payments 
end 

我試圖使用嵌套表格以允許用戶在創建新付款時修改項目的某些屬性。因此,如果該項目有一個標題,例如,創建一個新的支付方式的看法是這樣的:

<% form_for([@project, @payment]) do |f| %> 
    <% f.fields_for :project do |project_form| %> 
    <%= project_form.label :title %> 
    <%= project_form.text_field :title %> 
    <% end %> 

    <%= f.text_field :credit_card_number %> 

    ... 
<% end %> 

的付款控制器是非常標準:

class PaymentsController < ApplicationController 
    before_filter :load_project 

    # GET /payments/new 
    # GET /payments/new.xml 
    def new 
    @payment = @project.payments.build 

    respond_to do |format| 
     format.html # new.html.erb 
     format.xml { render :xml => @payment } 
    end 
    end 

    # POST /payments 
    # POST /payments.xml 
    def create 
    @payment = @project.payments.build(params[:payment]) 

    respond_to do |format| 
     if @payment.save 
     flash[:notice] = 'Payment was successfully created.' 
     format.html { redirect_to([@project, @payment]) } 
     format.xml { render :xml => @payment, :status => :created, :location => @payment } 
     else 
     format.html { render :action => "new" } 
     format.xml { render :xml => @payment.errors, :status => :unprocessable_entity } 
     end 
    end 
    end 

    private 
    def load_project 
     @project = Project.find(params[:project_id]) 
    end 
end 

什麼我發現是新的付款形式,我結束了這樣的事情:

<input id="payment_project_attributes_title" name="payment[project_attributes][title]" size="30" type="text" /> 
<input id="payment_project_attributes_id" name="payment[project_attributes][id]" type="hidden" value="56" /> 

(注意,自動創建#payment_project_attributes_id)

當提交表單時,軌(在該項目#56已經存在,要記住)收到此像這樣:

"payment"=>{"project_attributes"=>{"title"=>"test title", "id"=>"56"}, "credit_card_number"=>"41111111111111111"} 

而這裏的問題:當這是通過控制器上運行,它不將標題屬性應用於付款項目。

奇怪的是,如果我刪除了「id」=>「56」,項目的標題IS將被更新。下面是使用控制檯的例子:

ruby-1.8.7-p249 > Project.find(56) 
=> #<Project id: 56, title: nil, created_at: "2010-06-18 15:58:25", updated_at: "2010-06-18 16:01:37"> 
ruby-1.8.7-p249 > p=Project.find(56).payments.new({"project_attributes"=>{"title"=>"my new title", "id"=>"56"}}) 
=> #<Payment id: nil, project_id: 56, created_at: nil, updated_at: nil> 
ruby-1.8.7-p249 > p.project 
=> #<Project id: 56, title: nil, created_at: "2010-06-18 15:58:25", updated_at: "2010-06-18 16:01:37"> 
ruby-1.8.7-p249 > p=Project.find(56).payments.new({"project_attributes"=>{"title"=>"test title"}}) 
=> #<Payment id: nil, project_id: 56, created_at: nil, updated_at: nil> 
ruby-1.8.7-p249 > p.project 
=> #<Project id: nil, user_id: nil, title: "test title", created_at: nil, updated_at: nil> 

(注意第二payments.new,沒有ID,導致p.project.title被更新)

這似乎直接矛盾此門票:https://rails.lighthouseapp.com/projects/8994/tickets/3687-nested-attributes-with-belongs_to-only-supports-one-use-case

沒有任何人有什麼想法?

我應該注意到,我真的想做的是一層更復雜 - 我正在嘗試更新Project的user_attributes(在項目上使用belongs_to:user/accepting_nested_attributes_for:user),但我是如果我能弄清楚這一點,希望那隻會工作

回答

1

看來,既然你打電話基礎上的@聯想構建方法project.payments它已經知道項目ID是什麼。也許它不喜歡你試圖更新項目ID的事實嗎?

+0

此外,我認爲你的表格只適用於付款 <%form_for @payment do | f | %> 然後你的領域應該沒問題。 – Mike 2010-06-18 23:18:05