Jseb
Jseb

Reputation: 1934

Rails Nil don't understand the error

I have the following error

undefined method `[]' for nil:NilClass
app/controllers/events_controller.rb:60:in `create'

I am not sure what they mean by nil in this case. Here my controller and line 60 is where the arrow is

def create
    @event = current_customer.events.build(params[:event])
    @location = @event.locations.build(params[:location])
    --->@location.longitude = params[:location][:longitude]
    @location.latitude = params[:location][:latitude]
    respond_to do |format|
    if @location.save
        if @event.save
            format.html { redirect_to @event, notice: 'Event was successfully created.' }
            format.json { render json: @event, status: :created, location: @event }
          else
            format.html { render action: "new" }
            format.json { render json: @event.errors, status: :unprocessable_entity }
        end
      end
    end
  end

I have two models an event and a locations, I am create the two events at the same time and events has many locations. The longitude are attr_accesor longitude and latitude. hidden field type.

Upvotes: 0

Views: 102

Answers (3)

RubyFanatic
RubyFanatic

Reputation: 2281

params[:location] is very likely to be nil. Additionally, you should consider using nested model form to have cleaner code. Refer to the RailsCast on Nested Model Forms and the docs for fields_for.

Theoretically, your model classes should look something like this:

class Customer < ActiveRecord::Base
    ...
    has_many :events
    accepts_nested_attributes_for :events
    ...
end

class Event < ActiveRecord::Base
    ...
    has_one :location
    accepts_nested_attributes_for :location
    ...
end

class Location < ActiveRecord::Base
    ...
    belongs_to :event
    ...
end

your controller like this:

class EventsController < ApplicationController
    def new
        current_customer.events.build({}, {}) # instantiate 2 empty events            
    end

    def create
        current_customer.events.build(params[:event])
        if current_customer.save # should save all events and their associated location
            ...
        end
    end
end

and your view like this:

<%= form_for @customer do |f| %>
    ...
    <%= f.fields_for :events do |e| %>
        ...
        <%= e.fields_for :location, (e.build_location || e.location) do |l| %>
            <%= l.hidden_field :longitude %>
            <%= l.hidden_field :latitude %>
        <% end %>
        ...
    <% end %>
    ...
<% end %>

Upvotes: 2

Roger
Roger

Reputation: 7612

Write to your console:

logger.debug params[:location].class
logger.debug params[:location].inspect

I suspect the data coming is isn't what you expect it to be (i.e. [:longitude] is not part of the hash params[:location]).

Upvotes: 0

Alex
Alex

Reputation: 9471

Either params is nil, or, more likely, params[:location] is nil.

Imagine:

a = [[1,2], [3,4], [5,6], nil, [7,8]]
a[0][0]
=> 1
a[3][0]
undefined method `[]' for nil:NilClass

Because fourth element is nil, so we can't use the [] method on it..

The conclusion is that params[:location] is nil, such that when you're trying to access an element of what you think is an array, you get a method error, because NilClass doesn't have the [] method (whereas an Array does)

Upvotes: 2

Related Questions