Note that there are some explanatory texts on larger screens.

plurals
  1. PORails nested form with nested resource: update belongs_to association when creating new has_many
    text
    copied!<p>Hey guys, I've been beating my head against a wall with a particular use case for nested forms (I'm using Rails 2.3.5).</p> <p>Essentially I have Project and Payment models that looks like this</p> <pre><code>class Project &lt; ActiveRecord::Base has_many :payments end class Payment &lt; ActiveRecord::Base belongs_to :project accepts_nested_attributes_for :project end </code></pre> <p>I'm also using nested routing for these two resources:</p> <pre><code>map.resources :projects do |project| project.resources :payments end </code></pre> <p>I'm trying to use a nested form to allow the user to modify certain attributes of the Project when creating a new Payment. So if the Project has a title, for example, the view for creating a new Payment would look like this:</p> <pre><code>&lt;% form_for([@project, @payment]) do |f| %&gt; &lt;% f.fields_for :project do |project_form| %&gt; &lt;%= project_form.label :title %&gt; &lt;%= project_form.text_field :title %&gt; &lt;% end %&gt; &lt;%= f.text_field :credit_card_number %&gt; ... &lt;% end %&gt; </code></pre> <p>The Payments controller is pretty much standard:</p> <pre><code>class PaymentsController &lt; 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 =&gt; @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 =&gt; @payment, :status =&gt; :created, :location =&gt; @payment } else format.html { render :action =&gt; "new" } format.xml { render :xml =&gt; @payment.errors, :status =&gt; :unprocessable_entity } end end end private def load_project @project = Project.find(params[:project_id]) end end </code></pre> <p>What I'm finding is that on the new Payment form, I'm ending up with something like this:</p> <pre><code>&lt;input id="payment_project_attributes_title" name="payment[project_attributes][title]" size="30" type="text" /&gt; &lt;input id="payment_project_attributes_id" name="payment[project_attributes][id]" type="hidden" value="56" /&gt; </code></pre> <p>(Note the automatically created #payment_project_attributes_id)</p> <p>When the form is submitted, rails receives this like so (bear in mind that Project #56 already exists):</p> <pre><code>"payment"=&gt;{"project_attributes"=&gt;{"title"=&gt;"test title", "id"=&gt;"56"}, "credit_card_number"=&gt;"41111111111111111"} </code></pre> <p>And here's the problem: when this is run through the controller, it DOESN'T apply the title attribute to the Payment's Project.</p> <p>What's strange is that if I remove that <strong>"id"=>"56"</strong>, the Project's title IS updated. Here's an example using the console:</p> <pre><code>ruby-1.8.7-p249 &gt; Project.find(56) =&gt; #&lt;Project id: 56, title: nil, created_at: "2010-06-18 15:58:25", updated_at: "2010-06-18 16:01:37"&gt; ruby-1.8.7-p249 &gt; p=Project.find(56).payments.new({"project_attributes"=&gt;{"title"=&gt;"my new title", "id"=&gt;"56"}}) =&gt; #&lt;Payment id: nil, project_id: 56, created_at: nil, updated_at: nil&gt; ruby-1.8.7-p249 &gt; p.project =&gt; #&lt;Project id: 56, title: nil, created_at: "2010-06-18 15:58:25", updated_at: "2010-06-18 16:01:37"&gt; ruby-1.8.7-p249 &gt; p=Project.find(56).payments.new({"project_attributes"=&gt;{"title"=&gt;"test title"}}) =&gt; #&lt;Payment id: nil, project_id: 56, created_at: nil, updated_at: nil&gt; ruby-1.8.7-p249 &gt; p.project =&gt; #&lt;Project id: nil, user_id: nil, title: "test title", created_at: nil, updated_at: nil&gt; </code></pre> <p>(Note that the second payments.new, without the ID, causes p.project.title to be updated)</p> <p>This seems directly contradictory to this ticket: <a href="https://rails.lighthouseapp.com/projects/8994/tickets/3687-nested-attributes-with-belongs_to-only-supports-one-use-case" rel="nofollow noreferrer">https://rails.lighthouseapp.com/projects/8994/tickets/3687-nested-attributes-with-belongs_to-only-supports-one-use-case</a></p> <p>Does anybody have any thoughts?</p> <p>I should note that what I'm really trying to do is one layer more complex--I'm trying to update user_attributes for Project (using a belongs_to :user/accepts_nested_attributes_for :user on the Project) but I'm sort of hoping that will just <em>work</em> if I can figure this out.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload