I am using build
, fields_for
, and accepts_nested_attributes_for
to create a new registration note on the same form as a new registration (has many registration notes). Great.
Problem: On the edit form for the existing registration, I want another new registration note to be created, but I don't want to see a field for each of the existing registration notes.
I have this
class Registration < ActiveRecord::Base attr_accessible :foo, :bar, :registration_notes_attributes has_many :registration_notes accepts_nested_attributes_for :registration_notes end
and this
class RegistrationsController < ApplicationController def edit @registration = Registration.find(params[:id]) @registration.registration_notes.build end end
and in the view I am doing this:
<%= form_for @registration do |r| %> <%= r.text_field :foo %> <%= r.text_field :bar %> <%= r.fields_for :registration_notes do |n| %> <%= n.text_area :content %> <% end %> <% end %>
and it is creating a blank text area for a new registration note (good) and each existing registration note for that registration (no thank you).
Is there a way to only create a new note for that registration and leave the existing ones alone?
EDIT: My previous answer (see below) was bugging me because it's not very nice (it still loops through all the other registration_notes
needlessly). After reading the API a bit more, the best way to get the behaviour the OP wanted is to replace:
<%= r.fields_for :registration_notes do |n| %>
with:
<%= r.fields_for :registration_notes, @registration.registration_notes.build do |n| %>
fields_for
optionally takes a second parameter which is the specific object to pass to the builder (see the API), which is built inline. It's probably actually better to create and pass the new note in the controller instead of in the form though (just to move the logic out of the view).
Original answer (I was so close):
Just to clarify, you want your edit form to include a new nested registration note (and ignore any other existing ones)? I haven't tested this, but you should be able to do so by replacing:
<%= r.fields_for :registration_notes do |n| %>
with:
<%= r.fields_for @registration.registration_notes.build do |n| %>
EDIT: Okay, from a quick test of my own that doesn't work, but instead you can do:
<%= r.fields_for :registration_notes do |n| %> <%= n.text_area :content if n.object.id.nil? %> <% end %>
This will only add the text area if the id of the registration note is nil (ie. it hasn't been saved yet).
Also, I actually tested this first and it does work ;)
If you want to create a new registration form on your edit action, you can just instantiate a new registration_note object. Right now, your form is for the existing registration object.
I believe this is what you want:
class RegistrationsController < ApplicationController def edit @new_registration_note = RegistrationNote.new @registration = Registration.find(params[:id]) @registration.registration_notes.build end end
In your view, you should pass a hidden param that references the registration record id:
<%= form_for @new_registration_note do |r| %> <%= r.hidden_field :registration_id, :value => @registration.id %> <%= r.text_area :content %> <% end %>
Now, you can create your new registration note that belongs to @registration
. Make sure you have a column in your registration_notes
table to point to the registration. You can read more about associations here: http://guides.rubyonrails.org/association_basics.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With