0

I'm struggling to come up with the proper way to design a form that will allow me to input data for two different models. The form is for an 'Incident', which has the following relationships:

belongs_to              :customer
belongs_to              :user

has_one                 :incident_status

has_many                :incident_notes
accepts_nested_attributes_for :incident_notes, :allow_destroy => false

So an incident is assigned to a 'Customer' and a 'User', and the user is able to add 'Notes' to the incident. I'm having trouble with the notes part of the form. Here how the form is being submitted:

{"commit"=>"Create",
 "authenticity_token"=>"ECH5Ziv7JAuzs53kt5m/njT9w39UJhfJEs2x0Ms2NA0=",
 "customer_id"=>"4",
 "incident"=>{"title"=>"Something bad",
 "incident_status_id"=>"2",
 "user_id"=>"2",
 "other_id"=>"AAA01-042310-001",
 "incident_note"=>{"note"=>"This is a note"}}}

It appears to be attempting to add the incident_note as a field under 'Incident', rather than creating a new entry in the incident_note table with an incident_id foreign key linking back to the incident.

Here is the 'IncidentNote' model:

belongs_to :incident
belongs_to :user

Here is the form for 'Incident':

<% form_for([@customer,@incident]) do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :other_id, "ID" %><br />
    <%= f.text_field :capc_id %>
  </p>
  <p>
    <%= f.label :title %><br />
    <%= f.text_field :title %>
  </p>
    <p>
      <%= label_tag 'user', 'Assign to user?' %>
      <%= f.select :user_id, @users.collect {|u| [u.name, u.id]} %>
    </p>
    <p>
      <%= f.label :incident_status, 'Status?' %>
      <%= f.select :incident_status_id, @statuses.collect {|s| [s.name, s.id]} %>
    </p>
    <p>
      <% f.fields_for :incident_note do |inote_form| %>
        <%= inote_form.label :note, 'Add a Note' %>
        <%= inote_form.text_area :note, :cols => 40, :rows => 20 %>
      <% end %>
    </p>
  <p>
    <%= f.submit "Create" %>
  </p>
<% end %>

And finally, here are the incident_controller entries for New and Create.

New:

  def new
    @customer = current_user.customer
    @incident = Incident.new
    @users = @customer.users
    @statuses = IncidentStatus.find(:all)
    @incident_note = IncidentNote.new

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

Create:

  def create
    @users = @customer.users
    @statuses = IncidentStatus.find(:all)
    @incident = Incident.new(params[:incident])
    @incident.customer = @customer
    @incident_note = @incident.incident_note.build(params[:incident_note])
    @incident_note.user = current_user

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

I'm not really sure where to look at this point. I'm sure it's just a limitation of my current Rails skill (I don't know much). So if anyone can point me in the right direction I would be very appreciative. Please let me know if more information is needed!

Thanks!

1 Answer 1

1

Check api for fields_for method and scroll to one-to-many section.

Your model has many :incident_notes, not one incident_note, that is why it doesn't understand relationship and tries to find a field with this name.

So it should be:

  <% f.fields_for :incident_notes do |inote_form| %>
    <%= inote_form.label :note, 'Add a Note' %>
    <%= inote_form.text_area :note, :cols => 40, :rows => 20 %>
  <% end %>

It iterates through all incident_notes assigned to incident and produces fields for each of them.
You also have to build at least one note in you new action, otherwise there will be none:

  def new
    @incident = Incident.new
    @incident.incident_notes.build
    # ...
  end
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your response. I think that was the issue. Now I am getting other errors because I tinkered with it a bit more, so I can't confirm yet. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.