Intro

In this section we are going to dive deep into database migration.

Create new table

We use the model Bond to indicate a connection between one user and another. It has the state field to indicate the state of the connection.

Schema

Schema of Bound

ColumnData TypeOptions
idintPrimary key, non-null
user_idintForeign key(users), non-null
friend_idintForeign key(users), non-null
statestringNon-null

Possible value of state

StateDescription
requestingWhen a user sends a follow request to another user (which will be accepted automatically if it is a public account)
followingWhen a user is following another user
blockingWhen a user is blocked another user

Generate Migration File

Command to scaffold Bond

rails g model bond user_id:integer friend_id:integer state

Modify Migration File

After that, let’s enforce non-null constraints as shown below

class CreateBonds < ActiveRecord::Migration[6.1]
  def change
    create_table :bonds do |t|
      t.integer :user_id, null: false
      t.integer :friend_id, null: false
      t.string :state, null: false

      t.timestamps
    end
  ...

Next, let’s make user_id and friend_id a unique combination. This way, there is no way the table can have multiple bond records between the same user A and the same user B for those fields, respectively.

  def change
    create_table :bonds do |t|
      ...
    end
    add_index :bonds, [:user_id, :friend_id], unique: true
    add_foreign_key :bonds, :users, column: :user_id
    add_foreign_key :bonds, :users, column: :friend_id
  end

As we have bonds.user_id and bonds.friend_id referencing users.id, we add a foreign key for each of them in line 3 and 4.

Schema Statement

https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html