leonel
leonel

Reputation: 10224

Rails 3. render on validation error

I have a form where a user can enter payments for an invoice. So...

invoice has_many   :payments
payment belongs_to :invoice

The problem is, when there is a validation error, let's say the user doesn't enter a required payment date, I get this error...

undefined method invoice_number for nil:NilClass
Extracted source (around line #10):
7: 
8: <div class="content-box-content">
9:   <div class="tab-content default-tab" style="display: block; ">     
10:   <h4>Invoice #<%= @invoice.invoice_number %> for <%= @invoice.company.name %></h4>
11:     <p>Invoice Balance $<%= sprintf("%.2f", @invoice.balance) %></p>
12:   </div>
13: </div>

payments_controller.rb
----------------------
def new
  @invoice = Invoice.find(params[:invoice_id])
  @payment = @invoice.payments.build

  respond_to do |format|
    format.html
  end
end

def create
  @payment = Payment.new(params[:payment])
  respond_to do |format|
    if @payment.save
      format.html { redirect_to payments_path, notice: 'Payment was successfully created.' }
    else
      format.html { render action: "new" }
    end
  end
end

So I know I have to add @invoice to the create action, somewhere in render action: "new". How can I do this?

Upvotes: 0

Views: 326

Answers (1)

jstrong
jstrong

Reputation: 1607

Simply add @invoice = @payment.invoice before you do format.html { render action: "new" } and everything should work

def create
  @payment = Payment.new(params[:payment])
  respond_to do |format|
    if @payment.save
      format.html { redirect_to payments_path, notice: 'Payment was successfully created.' }
    else
      @invoice = @payment.invoice
      format.html { render action: "new" }
    end
  end
end

Calling render for a different action than the one being managed will only render the view of that action. It does not call the method of the action being rendered.

In other words: the format.html { render action: "new" } simply loads new.html.erb with the variables specified in the create action, def new is never even touched. As a result, the @invoice parameter does not exist since you never defined it in your create action.

Upvotes: 2

Related Questions