0

I have a rails app that has associated jobs and customers. A customer has_many jobs and a job belongs_to a customer.

On my customer show page, there is a link to create a new job:

<%= link_to "Add New Job", new_customer_job_path(@customer) %>

After clicking that link they are sent to a new form page for a new job. When the form is submitted, the request gets pushed to the jobs controller as follows:

class JobsController < ApplicationController
  before_action :set_job, only: [:show, :edit, :update, :destroy]

def index
  @jobs = Job.all
end

def show
end

def new
  @customer = Customer.find(params[:customer_id])
  @job = @customer.jobs.build
end

def edit
end


def create
  @job = Job.new(job_params)

respond_to do |format|
  if @job.save
    format.html { redirect_to customer_path(@customer), notice: 'Job was successfully created.' }
    format.json { render action: 'show', status: :created, location: @job }
  else
   format.html { render action: 'new' }
   format.json { render json: @job.errors, status: :unprocessable_entity }
  end
  end
end

def update
  respond_to do |format|
    if @job.update(job_params)
      format.html { redirect_to @job, notice: 'Job was successfully updated.' }
      format.json { head :no_content }
    else
      format.html { render action: 'edit' }
      format.json { render json: @job.errors, status: :unprocessable_entity }
    end
  end
end

def destroy
  @job.destroy
  respond_to do |format|
    format.html { redirect_to jobs_url }
    format.json { head :no_content }
  end
end

private
  # Use callbacks to share common setup or constraints between actions.
  def set_job
    @job = Job.find(params[:id])
  end

  # Never trust parameters from the scary internet, only allow the white list through.
  def job_params
    params.require(:job).permit(:box_count, :install_date)
  end
end

I receive the following error when the controller is trying to redirect after the form submission:

No route matches {:id=>nil} missing required keys: [:id]

Here is the line that the error calls out:

format.html { redirect_to customer_path(@customer), notice: 'Job was successfully created.' } 

I can see the ID being passed through in the params, but for some reason it does not like customer_path(@customer).

Here is my new job form:

<%= form_for([@customer, @job]) do |f| %>
 <% if @job.errors.any? %>
  <div id="error_explanation">
    <h2><%= pluralize(@job.errors.count, "error") %> prohibited this job from being saved:</h2>

    <ul>
    <% @job.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
<% end %>

<div class="field">
  <%= f.label :box_count %><br>
  <%= f.number_field :box_count %>
</div>
<div class="field">
  <%= f.label :install_date %><br>
  <%= f.text_field :install_date %>
</div>
<div class="actions">
  <%= f.submit %>
</div>
<% end %>

Anyone know what I am doing wrong?

Dustin James
  • 575
  • 9
  • 21
  • can you paste your controller code – derekyau Aug 05 '14 at 17:32
  • We'll need to see your form code, but it is a possible duplicate of http://stackoverflow.com/questions/2034700/form-for-with-nested-resources – robbrit Aug 05 '14 at 17:32
  • @derekyau Added - sorry, didn't want to clutter it up if this was a simple issue. – Dustin James Aug 05 '14 at 17:46
  • @robbrit Added the form code, don't think this is a duplicate of the question you referenced, I just finished working through that exact issue. This is at the back end - when the form is submitted it runs into an error being saved because the id is missing. – Dustin James Aug 05 '14 at 17:47
  • @customer was not initialized in this line: format.html { redirect_to customer_path(@customer), notice: 'Job was successfully created.' }. The action doesn't even mention it before this line. – Tiago Farias Aug 05 '14 at 17:51
  • @TiagoFarias ah, so in the create block I need to initialize the customer? – Dustin James Aug 05 '14 at 17:55

1 Answers1

2

@customer is never initialized. Try this:

def create
  @job = Job.new(job_params)

respond_to do |format|
  if @job.save
    @customer = @job.customer
    format.html { redirect_to customer_path(@customer), notice: 'Job was successfully created.' }
 ... 

Also your jobs_params must allow the customer_id:

  def job_params
    params.require(:job).permit(:box_count, :install_date)
    params.permit(:customer_id)
  end
Tiago Farias
  • 3,397
  • 1
  • 27
  • 30
  • Logic makes sense, but same error: No route matches {:id=>nil} missing required keys: [:id] – Dustin James Aug 05 '14 at 18:00
  • 1
    Ah, in job_params, you need to allow customer_id also. – Tiago Farias Aug 05 '14 at 18:03
  • do I need to pass the id into a form field on the new form to add it to the DB? If it's saying it's nil, then perhaps that's the issue here? – Dustin James Aug 05 '14 at 18:03
  • I added this in the create block and it worked: @customer = Customer.find(params[:customer_id]) – Dustin James Aug 05 '14 at 18:09
  • Thanks Tiago, that makes a lot of sense - I guess what I learned here was that even though @customer was initialized elsewhere in the controller, it's still local and needs to be done in each block that it is needed. – Dustin James Aug 05 '14 at 18:11
  • 1
    Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/58717/discussion-between-tiago-farias-and-dustin-james). – Tiago Farias Aug 05 '14 at 18:17