sathish_at_madison
sathish_at_madison

Reputation: 833

Simple association issue with rails and not working

Here is my Schema file

ActiveRecord::Schema.define(version: 20150917104809) do
    create_table "customers", force: :cascade do |t|
         t.datetime "created_at", null: false
         t.datetime "updated_at", null: false
         t.string   "name"
    end
    create_table "orders", force: :cascade do |t|
        t.datetime "created_at",   null: false
        t.datetime "updated_at",   null: false
        t.datetime "order_date"
        t.integer  "customers_id"
    end
end

Here are the models

class Customer < ActiveRecord::Base
  has_many :orders, dependent: :destroy
end

class Order < ActiveRecord::Base
  belongs_to :customer
end

The migration file for association is

class AddForeignKeyToOrders < ActiveRecord::Migration
  def change
    add_reference :orders, :customers
  end
end

Following the simple rails assoc example in the link

I created a customer record using the command

Customer.create(name: 'Someone')

and now trying to create the order

@order = @customer.orders.create(order_date: Time.now)

Am getting an error with a NilClass

NoMethodError: undefined method `orders' for nil:NilClass

May be another pair of eyes of help to tell what am I doing wrong.

Upvotes: 0

Views: 61

Answers (2)

Richard Peck
Richard Peck

Reputation: 76784

To add to @ghr's answer, your error is thus: for nil:NilClass

This means that you're trying to call a method on an object which doesn't exist. Ruby actually assigns nil classes to an NilClass object, so it's errors aren't easily recognized unless you've spent time with them.

--

You have to assign Customer.create... to a variable, otherwise Rails doesn't have the data stored for you to work with:

@customer = Customer.create(name: "Someone")
@customer.orders.create

As a note, you don't need order_date in your Order model - created_at will handle that. If you removed the order_date column from your table, you'd be able to call the following:

#app/models/order.rb
class Order < ActiveRecord::Base
   belongs_to :customer
   alias_attribute :date, :created_at
end

@customer.orders.first.date

Upvotes: 1

ghr
ghr

Reputation: 647

You need to assign the return value of create to @customer:

@customer = Customer.create(name: 'Someone')
@order = @customer.orders.create(order_date: Time.now)

It also looks like you have a typo in your schema. It should be:

t.integer  "customer_id"

EDIT: Your migration file is incorrect. It should be:

class AddForeignKeyToOrders < ActiveRecord::Migration
  def change
    add_reference :orders, :customer
  end
end

See the add_reference API docs.

Upvotes: 3

Related Questions