2010-06-18 164 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