horaciovelvetine
horaciovelvetine

Reputation: 59

Migrations in Rails, difference between null and optional options?

Im working on learning Rails, and have found that the details are where you can really end up sinking yourself in the future. As I'm creating a very simple store, doing migrations I have a few belongs_to's that are optional object relationships. As I was reading trying to better understand null here:

Understanding rails migration statement (:null => false)

It occurred to me that using null: true would allow that column to be null, and I was couldn't find any information / questions addressing the difference between:

create_table :items do |t|
  
  ...
  t.belongs_to :shopping_cart, null: true
  ...

end

and

create_table :items do |t|
  
  ...
  t.belongs_to :shopping_cart, optional: true
  ...

end

What should I be doing for this kind of optional relationship, I'm new to Ruby/Rails but "convention over configuration" has me wanting to understand the right way to do this. Thanks so much!

Upvotes: 4

Views: 2232

Answers (1)

ellitt
ellitt

Reputation: 833

I think you may be confused about how optional works in a belongs_to relationship.

In a migration file, you're telling the database how a table is going to be structured. What columns are called, what kind of data they hold, whether or not NULL is an acceptable value, etc. This relates directly to your model code through the ActiveRecord ORM that Rails uses.

So in a migration, null: true means at the database level that NULL is an acceptable value for the given column. null: false would mean that NULL is not acceptable and that you always expect something to be stored there. Generally, null: false is used in conjunction with a default so that there's always a value in the column even if it's not specified when the record is created.

optional is used in the model code itself to tell ActiveRecord that a belongs_to relationship is expected, but it may not exist and that's ok. In your case, that would look something like this:

class Item < ApplicationRecord
  belongs_to :shopping_cart, optional: true
end

That means that an item may have a shopping_cart_id present in the database, but it doesn't have to. Items can exist with a shopping_cart_id column that contains NULL.

Really null: true and optional aren't directly related. Nullability at the database level is determined by what's in a migration file. The presence of a foreign_key in a belongs_to relationship like items belonging to shopping carts is more about the model code than it is about the migration code.

Upvotes: 6

Related Questions