分享

[Rails][notes]Active Record Migrations(1)-官網閱讀紀錄[9]

記錄自己官網文件閱讀的注釋與筆記
主要也是訓練自己閱讀英文挑戰
https://guides.rubyonrails.org/getting_started.html
官網 文件 注釋 rails

Photo by Jorge Tung on Unsplash

Active Record Migrations

Active Record 中的一個功能Migrations,它能使你隨著時間的推移開發你的資料庫的schema。而不是在純SQL語法模式中撰寫,Migrations允許你使用Ruby DSL來描述需要修改的資料表。
閱讀後你將會學到
  • 使用產生器來創建Migrations
  • 使用Active Record提供的操作資料庫方法
  • 使用rails 命令 來操作Migrations 和 schema
  • Migrations 和 schema.rb的關係

1 Migration Overview

Migrations是一種遂著時間改變仍以一制性方法來修改資料庫的便利方法。
它使用的是Ruby DSL,讓你不用再動手寫SQL,讓你的資料庫架構與修改更加獨立。你甚至可以想成每一個migration 就像是一個新版本的資料庫。schema一開始並沒有內容,隨著每一次的migration而增加、修改、刪除它的內容。Active Record 將會記錄隨著時間軸而更新你的schema。Active Record會將你更新的schema匹配到你的資料庫。
  

class CreateProducts < ActiveRecord::Migration[6.0]

  def change

    create_table :products do |t|

      t.string :name

      t.text :description


      t.timestamps

    end

  end

end

這一個migration將新增一個products資料表而這個資料表有擁有兩個欄位,一個是 name 資料類別是string,另一個欄位是description資料類別是text。而rails 隱藏了一個自動添加的主鍵(primary key) id;這也是所有Active Record默認添加的主鍵,timestamps 是一個巨集,他將會添加兩個欄位一個是created_at,另一個是updated_at。這兩個欄位若存在將有Active Record管理。
注意!這裡我們定義了即時的改變,在執行migration前我們並沒有這個資料表,然而在執行後這個資料表將會存在而Active Record將會記錄這一切,並且知道如果我們需要回朔Active Record會採用最好的方法去回朔,所以當你執行回朔指令,Active Record會把這個資料表刪除。
若是資料庫支援回朔等功能,migration將含在資料庫功能中執行,若是資料庫不支援,當發生migration失敗,就需要手動進行回朔修改。
若是你需要進行一些Active Record不具備的功能可以嘗試使用reversible
  

class ChangeProductsPrice < ActiveRecord::Migration[6.0]

  def change

    reversible do |dir|

      change_table :products do |t|

        dir.up   { t.change :price, :string }

        dir.down { t.change :price, :integer }

      end

    end

  end

end

或是可以使用up 或down 代替change
  

class ChangeProductsPrice < ActiveRecord::Migration[6.0]

  def up

    change_table :products do |t|

      t.change :price, :string

    end

  end


  def down

    change_table :products do |t|

      t.change :price, :integer

    end

  end

end

2 Creating a Migration

2.1 Creating a Standalone Migration

Migrations 每一個migration class的檔案將儲存在db/migrate。
它的命名方式是YYYYMMDDHHMMSS_create_products.rb,就是說使用
UTC的時間戳加上底線再加上migration名稱。而create_products會定義出一個類別名為CreateProducts,若是20080906120001_add_details_to_products.rb則定義為AddDetailsToProducts的類別,rails 透過這些時間戳來判斷執行的先後順序。若是你要自己手動建立請要注意先前的排序。當然自己建立時間戳記並不是一件有趣的事情。因此rails也提供了產生器。
  

bin/rails generate migration AddPartNumberToProducts

這將會產生一個空的 migration
  

class AddPartNumberToProducts < ActiveRecord::Migration[6.0]

  def change

  end

end

產生器會將時間戳加在檔案名稱上,檔案名稱依照命名約定為複數型態
也可以在創建時添加需要添加的欄位名稱與資料型態下
  

bin/rails generate migration AddPartNumberToProducts part_number:string

將會產生
  

class AddPartNumberToProducts < ActiveRecord::Migration[6.0]

  def change

    add_column :products, :part_number, :string

  end

end

如果要為新添加的欄位加上一個索引 index 可以這樣寫
bin/rails generate migration AddPartNumberToProducts part_number:string:index
將會產生
  

class AddPartNumberToProducts < ActiveRecord::Migration[6.0]

  def change

    add_column :products, :part_number, :string

    add_index :products, :part_number

  end

end

當然也可以將其刪除
  

bin/rails generate migration RemovePartNumberFromProducts part_number:string


產生
  

class RemovePartNumberFromProducts < ActiveRecord::Migration[6.0]

  def change

    remove_column :products, :part_number, :string

  end

end

當然也可以一次產出多個欄位
  

bin/rails generate migration AddDetailsToProducts part_number:string price:decimal

產生
  

class AddDetailsToProducts < ActiveRecord::Migration[6.0]

  def change

    add_column :products, :part_number, :string

    add_column :products, :price, :decimal

  end

end

如果名稱使用CreateXXX 將產生一個創建表格
  

bin/rails generate migration CreateProducts name:string part_number:string

產生
  

class CreateProducts < ActiveRecord::Migration[6.0]

  def change

    create_table :products do |t|

      t.string :name

      t.string :part_number


      t.timestamps

    end

  end

end


無論如何產生器提供一個建立表個的樣本 你可以透過db/migrate/YYYYMMDDHHMMSS_add_details_to_products.rb來修改編輯你的檔案,當然也可以使用references(belongs_to)來產生一個用來連結另一個表單的欄位。
  

bin/rails generate migration AddUserRefToProducts user:references

產生
  

class AddUserRefToProducts < ActiveRecord::Migration[6.0]

  def change

    add_reference :products, :user, foreign_key: true

  end

end


這將會產生出user_id 來讓products相依user
也可以使用JoinTable
  

bin/rails generate migration CreateJoinTableCustomerProduct customer product

產生
  

class CreateJoinTableCustomerProduct < ActiveRecord::Migration[6.0]

  def change

    create_join_table :customers, :products do |t|

      # t.index [:customer_id, :product_id]

      # t.index [:product_id, :customer_id]

    end

  end

end

將會生一個多對多的資料表

2.2 Model Generators

當建立model與scaffold時也會產生出migrations。這個migrations的欄位,可以在建立model指令時填入你需要的欄位。
  

bin/rails generate model Product name:string description:text

他將會為你產出
  

class CreateProducts < ActiveRecord::Migration[6.0]

  def change

    create_table :products do |t|

      t.string :name

      t.text :description


      t.timestamps

    end

  end

end

2.3 Passing Modifiers

在使用指令建立時可以透過一些修飾字搭配角括號來使用
  

bin/rails generate migration AddDetailsToProducts 'price:decimal{5,2}' supplier:references{polymorphic}

而產生的migration為
  

class AddDetailsToProducts < ActiveRecord::Migration[6.0]

  def change

    add_column :products, :price, :decimal, precision: 5, scale: 2

    add_reference :products, :supplier, polymorphic: true

  end

end

#官網  #文件  #注釋  #rails 
分類:學習

評論
上一篇
  • [Rails][notes]Active Record Basics-官網閱讀紀錄[8]
  • 下一篇
  • [Rails][notes]Active Record Migrations(2)-官網閱讀紀錄[10]
  • 更多文章
    載入中... 沒有更多了