Getting undefined method `values_at' for nil:NilClass using nested_form_for

孤街浪徒 提交于 2019-12-22 10:53:51

问题


I'm using nested_form gem from ryanb and it doesn't seem to be working properly. The remove link doesn't work (I installed the //= require jquery_nested_form properly and it looks like it's loading but i keep getting this error:

undefined method `values_at' for nil:NilClass

when i go to add:

= f.link_to_add "Add a line item", :invoice_line_items

also, without that line it works but the remove link doesn't do anything:

line_item.link_to_remove "Remove this line item"

here's my code:

.row-fluid
  .span10.offset1
    = nested_form_for(@invoice) do |f|
      - if @invoice.errors.any?
        #error_explanation
          %h2
            = pluralize(@invoice.errors.count, "error")
            prohibited this invoice from being saved:
          %ul
            - @invoice.errors.full_messages.each do |msg|
              %li= msg
      .fieldset
        %legend
          = "New Invoice for #{@client.name}"
        .form-horizontal
          .pull-left
            .control-group
              %label.control-label{:style => "width: 100px;"}
                Invoice ID
              .controls{:style => "margin-left: 120px;"}
                = f.text_field :client_invoice_id, :class => "input-small", :placeholder => @invoice_count_placeholder
            .control-group
              %label.control-label{:style => "width: 100px;"}
                Due Date
              .controls{:style => "margin-left: 120px;"}
                = f.select :payment_term, @payment_terms, { :required => "true" }, { :class => "span10" }
          .pull-right
            .control-group
              %label.control-label
                Issue Date
              .controls{:style => "margin-right: 60px;"}
                = f.text_field :issue_date, :id => "date-picker", :class => "input-small", :required => "true"
            .control-group
              %label.control-label
                Discount
              .controls{:style => "margin-right: 60px;"}
                .input-append
                  = f.text_field :discount, :class => "input-small", :placeholder => "Optional"
                  %span.add-on %
        .row-fluid
          %table.table
            = f.fields_for :invoice_line_item do |line_item|
              %tr
                %th
                %th.span8 Description
                %th.span1 Quantity
                %th.span1 Rate
                %th.span1 Amount
              %tr
                %td= line_item.link_to_remove "Remove this line item"
                %td= line_item.text_field :description
                / %td= text_area_tag 'body', nil, :style => "width:96%;"
                %td= text_field_tag 'hello', nil, :class => "input-mini"
                %td= text_field_tag 'hello', nil, :class => "input-mini"
                %td $99.99

            = f.link_to_add "Add a line item", :invoice_line_items
        .form-actions
          = f.submit "Preview Invoice", :class => "btn btn-primary pull-right"

any idea what i'm doing wrong? I want to easily be able to add line items to the invoice and then save the whole thing. Here's my associations:

class Invoice < ActiveRecord::Base
  ## ASSOCIATIONS ##
  belongs_to :user
  belongs_to :client
  has_many :invoice_line_items
  ## NESTED ATTRIBUTES ##
  accepts_nested_attributes_for :invoice_line_items, :allow_destroy => true

class InvoiceLineItem < ActiveRecord::Base
  ## ASSOCIATIONS ##
  belongs_to :invoice

EDIT: here's my invoices controller new action:

def new
    @client = current_user.clients.find(params[:client_id])
    @invoice = Invoice.new(:client_id => @client.id)
    @payment_terms = Invoice.payment_terms

    if @client.invoices.count > 0
      @invoice_count_placeholder = "Last used: #{@client.invoices.last.client_invoice_id}"
    else
      @invoice_count_placeholder = ""
    end

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @invoice }
    end
  end

回答1:


I was stuck in the same "undefined method" error and everything worked fine after I changed the first parameter of the f.fields_for call to the plural form, just like the has_many association. So in your case it should be:

= f.fields_for :invoice_line_items do |line_item|

since the association in the Invoice model is has_many :invoice_line_items

Hope it helps someone.




回答2:


It looks like you have two separate problems.

1) The remove link doesn't do anything. What version of Rails are you using? The asset pipeline wasn't added until 3.1, so if you are using something lower you can just follow the instructions on Github under 'Non Asset Pipeline Setup' which might solve issue one.

2) Using the link_to_add helper gives you an error. I peeked at the code here https://github.com/ryanb/nested_form/blob/master/lib/nested_form/builder_mixin.rb

The method calls values_at on

@fields[fields_blueprint_id]

which, according to your error message, is apperently nil. I got a lost looking at Ryan's code. I don't see how this value gets set, so I can't do much to help you figure out why this value is nil. But if I had to guess, it's because you didn't add

attr_accessible :invoice_line_items_attributes

to your Invoice model




回答3:


Here's what I came up with. If there were no items on the nested side of the relationship - say, if the book had no authors - I got the error. When I loaded the @book in the controller, I tried checking to see if the authors array was empty, and adding a new, empty Author if it was. When I did that, the nested form never saw an empty relation, and the errors went away.

I suspect this is a gotcha that could be coded out of nested_form if anyone wanted to do it and submit the pull request.



来源:https://stackoverflow.com/questions/15777038/getting-undefined-method-values-at-for-nilnilclass-using-nested-form-for

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!