分享

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

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

Photo by bruno maia from FreeImages

3 Writing a Migration

使用產生器產生Migration後就可以開始工作

3.1 Creating a Table

create_table 是最基本之一。但大多數的時候會使用model 產生器來產生。
  

create_table :products do |t|

  t.string :name

end

這樣將會products 資料表產生一個叫name的欄位,以及接下來會討論的id。默認中,create_table會建立一個主鍵id,你也可以使用:primary_key來更改它,如果你不需要主鍵可以使用id: false,也可以使用:options來對資料庫做指定的SQL操作。如下
  

create_table :products, options: "ENGINE=BLACKHOLE" do |t|

  t.string :name, null: false

end

這將會把ENGINE=BLACKHOLE添加在建立資料表中。
也可以透過:comment 這個選項來為資料表做描述,進而使用資料庫工具來查看它。像是MySQL Workbench或是PgAdmin,強烈建議在大型資料庫設計中添加注釋,這樣有助於維護,目前只有MySQL 和 PostgreSQL 支援。

3.2 Creating a Join Table

create_join_table 將會建立一個HABTM(has and belongs to many) 
典型的用法是
  

create_join_table :products, :categories

這將會建立一個擁有category_id與product_id兩個欄位的categories_products 資料表,欄位的預設選項是null: false,可以在:column_options修改預設值。create_join_table :products, :categories, column_options: { null: true }
  

create_join_table :products, :categories, column_options: { null: true }

create_join_table 透過前兩個參數來得知需要連接的兩個資料表,如果需要自己定義表格名稱可以透過:table_name這個選項來定義。
  

create_join_table :products, :categories, table_name: :categorization

這樣將會定義出categorization 的資料表。
create_join_table 也接受使用區塊的方式,可以透過這樣來增加索引或更多欄位。
  

create_join_table :products, :categories do |t|

  t.index :product_id

  t.index :category_id

end

3.3 Changing Tables

create_table相似的change_table,用於表格已經存在,它使用起來與create_table非常相似,但需要使用物件與區塊上更多的技巧。
  

change_table :products do |t|

  t.remove :description, :name

  t.string :part_number

  t.index :part_number

  t.rename :upccode, :upc_code

end

刪除description和name 欄位 ,建立part_number為一個字串資料型態的欄位。並且為它增加一個index,最後將upccode改名為upc_code

3.4 Changing Columns

就像是remove_columnadd_column,rails 也提供了change_column。
  

change_column :products, :part_number, :text

這將會將資料表products中的part_number資料型態修改為text,change_column這個指令是不可逆的。
除了change_column,  change_column_nullchange_column_default專門用來修改預設值。
  

change_column_null :products, :name, false

change_column_default :products, :approved, from: true, to: false

這將會把:name 資料欄位設定為 NOT NULL
:approved預設為false。

3.5 Column Modifiers

欄位修飾符可以用於建立與修改的時後
  • limit : 用於string/text/binary/integer 設定最大值
  • precision:用於定義精確decimal,設定數字位數的總數
  • scale:用於定義精確decimal,設定小數數字位數的總數
  • polymorphic:用於是設定belongs_to關聯加上type
  • null:用於是否允許NULL
  • default:設定欄位初始值,若設定動態數值如日期,預設只會是第一次當下的日期
  • comment:用於添加註釋

3.6 Foreign Keys

不是必須的,單可以透過外鍵的約束使資料更完整
  

add_foreign_key :articles, :authors

這將會為資料表articles新增一個author_id的外鍵。這個外鍵會相依於authors的id。
如果無法由資料表來推測使用主鍵可以使用:column and :primary_key來設定
Rails 會產生一個名字使用fk_rails_當前綴搭配10個隨機字元,可以使用:name來修改。
移除外鍵
  

# let Active Record figure out the column name

remove_foreign_key :accounts, :branches


# remove foreign key for a specific column

remove_foreign_key :accounts, column: :owner_id


# remove foreign key by name

remove_foreign_key :accounts, name: :special_fk_name

3.7 When Helpers aren't Enough

如果Active Record提供的功能不夠使用,可以使用execute執行SQL
  

Product.connection.execute("UPDATE products SET price = 'free' WHERE 1=1")

3.8 Using the change Method

目前change支援的方法
change_table 在區塊不調用change, change_defaultremove 的情況下是可逆的

3.9 Using reversible

  

當migrations過於複雜,Active Record無法自動處理時可以透過up或是down來指定。

class ExampleMigration < ActiveRecord::Migration[6.0]

  def change

    create_table :distributors do |t|

      t.string :zipcode

    end


    reversible do |dir|

      dir.up do

        # add a CHECK constraint

        execute <<-SQL

          ALTER TABLE distributors

            ADD CONSTRAINT zipchk

              CHECK (char_length(zipcode) = 5) NO INHERIT;

        SQL

      end

      dir.down do

        execute <<-SQL

          ALTER TABLE distributors

            DROP CONSTRAINT zipchk

        SQL

      end

    end


    add_column :users, :home_page_url, :string

    rename_column :users, :email, :email_address

  end

end

reversible可以確保資料執行的步驟,如例子中down區塊會在home_page_url移除及distributors刪除前執行。

3.10 Using the up/down Methods

你仍然可以在change中使用舊式 up and down,up表示你的migration將要做一個轉換,而down 將意味著你要回朔至up轉換前,換句話說先執行up在執行down則等同沒有改變。如果你在up中建立資料表應在down中刪除,明確的做法是在down操作up中的逆向行為
  

class ExampleMigration < ActiveRecord::Migration[6.0]

  def up

    create_table :distributors do |t|

      t.string :zipcode

    end


    # add a CHECK constraint

    execute <<-SQL

      ALTER TABLE distributors

        ADD CONSTRAINT zipchk

        CHECK (char_length(zipcode) = 5);

    SQL


    add_column :users, :home_page_url, :string

    rename_column :users, :email, :email_address

  end


  def down

    rename_column :users, :email_address, :email

    remove_column :users, :home_page_url


    execute <<-SQL

      ALTER TABLE distributors

        DROP CONSTRAINT zipchk

    SQL


    drop_table :distributors

  end

end

若是migration不可逆應添加ActiveRecord::IrreversibleMigration在down
這樣下一個使用者在回朔時會接收到拋出的警告

3.11 Reverting Previous Migrations

你可以透過Active Record的能力revert回朔migrations。
  

require_relative "20121212123456_example_migration"


class FixupExampleMigration < ActiveRecord::Migration[6.0]

  def change

    revert ExampleMigration


    create_table(:apples) do |t|

      t.string :variety

    end

  end

end

revert也接受使用區塊,取消的行為寫在區塊中,假設已經做了migration想要添加Active Record 的驗證用CHECK來驗證驗證郵遞區號。
  

class DontUseConstraintForZipcodeValidationMigration < ActiveRecord::Migration[6.0]

  def change

    revert do

      # copy-pasted code from ExampleMigration

      reversible do |dir|

        dir.up do

          # add a CHECK constraint

          execute <<-SQL

            ALTER TABLE distributors

              ADD CONSTRAINT zipchk

                CHECK (char_length(zipcode) = 5);

          SQL

        end

        dir.down do

          execute <<-SQL

            ALTER TABLE distributors

              DROP CONSTRAINT zipchk

          SQL

        end

      end


      # The rest of the migration was ok

    end

  end

end

若不使用revert處理 可以把create_table 與 reversible 互換,把create_table改成drop_table,最後把up與down 的程式碼對換。這就是revert 做的事情。
#回朔  #官網  #文件  #注釋  #筆記 
分類:學習

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