模型
一、Active Record 基礎(chǔ)
介紹Models治泥,數(shù)據(jù)庫(kù)持久性以及Active Record模式
- Active Record是什么芹血?
Active Record 是 MVC 中的 M(模型),負(fù)責(zé)處理數(shù)據(jù)和業(yè)務(wù)邏輯资昧。
注意:這里業(yè)務(wù)邏輯在Model處理酬土。
Active Record負(fù)責(zé)創(chuàng)建和使用需要持久存入數(shù)據(jù)庫(kù)的數(shù)據(jù)。Active Record實(shí)現(xiàn)了Active Record模式格带,是一種對(duì)象關(guān)系映射系統(tǒng)撤缴。
1-1)Active Record模式
在Active Record模式中,對(duì)象中既有持久存儲(chǔ)的數(shù)據(jù)叽唱,也有針對(duì)數(shù)據(jù)庫(kù)的操作屈呕。Active Record模式吧數(shù)據(jù)存取邏輯作為對(duì)象的一部分,處理對(duì)象的用戶知道如何把數(shù)據(jù)寫(xiě)入數(shù)據(jù)庫(kù)棺亭,還知道如何從數(shù)據(jù)庫(kù)取出數(shù)據(jù)虎眨。
1-2)對(duì)象關(guān)系映射
對(duì)象關(guān)系映射(ORM)Object-Relational-Mapping
是一種技術(shù)手段,吧應(yīng)用中的對(duì)象和關(guān)系型數(shù)據(jù)庫(kù)中的數(shù)據(jù)表連接起來(lái)镶摘。使用ORM嗽桩,應(yīng)用中對(duì)象的屬性和對(duì)象之間的關(guān)系可以通過(guò)一種簡(jiǎn)單的方法從數(shù)據(jù)庫(kù)中獲取,無(wú)需直接編寫(xiě)SQL語(yǔ)句凄敢,也不過(guò)度依賴特定的數(shù)據(jù)庫(kù)種類碌冶。
1-3)用作ORM框架的Active Record
Active Record作用:
- 表示模型和其中的數(shù)據(jù)
- 表示模型之間的關(guān)系
- 通過(guò)相關(guān)聯(lián)的模型表示繼承層次結(jié)構(gòu)
- 持久存入數(shù)據(jù)庫(kù)之前,驗(yàn)證模型
- 以面向?qū)ο蟮姆绞教幚頂?shù)據(jù)庫(kù)操作
2)Active Record中的約定大于配置
原則
使用其他編程語(yǔ)言或框架開(kāi)發(fā)應(yīng)用時(shí)涝缝,可能必須要編寫(xiě)很多配置代碼扑庞。大多數(shù) ORM 框架都是這樣。但是拒逮,如果遵循 Rails 的約定嫩挤,創(chuàng)建 Active Record 模型時(shí)不用做多少配置(有時(shí)甚至完全不用配置)。Rails 的理念是消恍,如果大多數(shù)情況下都要使用相同的方式配置應(yīng)用岂昭,那么就應(yīng)該把這定為默認(rèn)的方式。所以,只有約定無(wú)法滿足要求時(shí)约啊,才要額外配置邑遏。
2-1)命名約定
默認(rèn)情況下,Active Record使用一些命名約定恰矩,查找模型和數(shù)據(jù)庫(kù)表之間的映射關(guān)系记盒。Rails吧模型的類名轉(zhuǎn)換為復(fù)數(shù),然后查找對(duì)應(yīng)的數(shù)據(jù)表外傅。
eg:
模型類名為Book, 數(shù)據(jù)庫(kù)表 books
Rails提供的單復(fù)數(shù)轉(zhuǎn)換功能很強(qiáng)大纪吮,常見(jiàn)和不常見(jiàn)的轉(zhuǎn)換方式都能處理。
模型類:?jiǎn)螖?shù)萎胰,每個(gè)單詞的首寫(xiě)字母應(yīng)該大寫(xiě) BookClub
數(shù)據(jù)庫(kù)表: 復(fù)數(shù)碾盟,下劃線分隔單詞 book_clubs
2-2)模式約定
根據(jù)字段的作用不同,Active Record對(duì)數(shù)據(jù)庫(kù)表中的字段命名也做了相應(yīng)的約定:
外鍵:使用 singularized_table_name_id 形式命名技竟,例如 item_id冰肴,order_id。創(chuàng)建模型關(guān)聯(lián)后榔组,Active Record 會(huì)查找這個(gè)字段熙尉;
主鍵:默認(rèn)情況下,Active Record使用整數(shù)字段id作為表的主鍵搓扯。使用Active Record遷移創(chuàng)建數(shù)據(jù)庫(kù)表時(shí)检痰,會(huì)自動(dòng)創(chuàng)建這個(gè)字段。
還有一些可選的字段锨推,能為 Active Record 實(shí)例添加更多的功能:
created_at:創(chuàng)建記錄時(shí)攀细,自動(dòng)設(shè)為當(dāng)前的日期和時(shí)間;
updated_at:更新記錄時(shí)爱态,自動(dòng)設(shè)為當(dāng)前的日期和時(shí)間谭贪;
lock_version:在模型中添加樂(lè)觀鎖;
type:讓模型使用單表繼承锦担;
(association_name)_type:存儲(chǔ)多態(tài)關(guān)聯(lián)的類型俭识;
(table_name)_count:緩存所關(guān)聯(lián)對(duì)象的數(shù)量。比如說(shuō)洞渔,一個(gè) Article 有多個(gè) Comment套媚,那么 comments_count 列存儲(chǔ)各篇文章現(xiàn)有的評(píng)論數(shù)量;
雖然這些字段是可選的磁椒,但在 Active Record 中是被保留的堤瘤。如果想使用相應(yīng)的功能,就不要把這些保留字段用作其他用途浆熔。例如本辐,type 這個(gè)保留字段是用來(lái)指定數(shù)據(jù)庫(kù)表使用單表繼承(Single Table Inheritance,STI)的。如果不用單表繼承慎皱,請(qǐng)使用其他的名稱老虫,例如“context”,這也能表明數(shù)據(jù)的作用茫多。
3)創(chuàng)建Active Record模型
創(chuàng)建 Active Record 模型的過(guò)程很簡(jiǎn)單祈匙,只要繼承 ApplicationRecord 類就行了:
class Product < ApplicationRecord
end
這代碼會(huì)創(chuàng)建Product模型,對(duì)應(yīng)于數(shù)據(jù)庫(kù)中的products表天揖。
上面的代碼會(huì)創(chuàng)建 Product 模型夺欲,對(duì)應(yīng)于數(shù)據(jù)庫(kù)中的 products 表。同時(shí)今膊,products 表中的字段也映射到 Product 模型實(shí)例的屬性上些阅。假如 products 表由下面的 SQL 語(yǔ)句創(chuàng)建:
CREATE TABLE products (
id int(11) NOT NULL auto_increment,
name varchar(255),
PRIMARY KEY (id)
);
按照這樣的數(shù)據(jù)表結(jié)構(gòu),可以編寫(xiě)下面的代碼:
p = Product.new
p.name = "Some Book"
puts p.name # "Some Book"
4)覆蓋命名約定
如果想使用其他的命名約定万细,或者在Rails應(yīng)用張使用即有的數(shù)據(jù)庫(kù)可以嗎?沒(méi)問(wèn)題纸泄,默認(rèn)的約定能夠輕易覆蓋赖钞。
ApplicationRecord 繼承自 ActiveRecord::Base,后者定義了一系列有用的方法聘裁。使用 ActiveRecord::Base.table_name= 方法可以指定要使用的表名:
class Product < ApplicationRecord
self.table_name = "my_products"
end
如果這么做雪营,還要調(diào)用 set_fixture_class 方法,手動(dòng)指定固件(my_products.yml)的類名:
class ProductTest < ActiveSupport::TestCase
set_fixture_class my_products: Product
fixtures :my_products
...
end
還可以使用 ActiveRecord::Base.primary_key= 方法指定表的主鍵:
class Product < ApplicationRecord
self.primary_key = "product_id"
end
5)CRUD:讀寫(xiě)數(shù)據(jù)
CURD 是四種數(shù)據(jù)操作的簡(jiǎn)稱:C 表示創(chuàng)建衡便,R 表示讀取献起,U 表示更新,D 表示刪除镣陕。Active Record 自動(dòng)創(chuàng)建了處理數(shù)據(jù)表中數(shù)據(jù)的方法谴餐。增刪改查。
5-1)create增
Active Record 對(duì)象可以使用散列創(chuàng)建呆抑,在塊中創(chuàng)建岂嗓,或者創(chuàng)建后手動(dòng)設(shè)置屬性。new 方法創(chuàng)建一個(gè)新對(duì)象鹊碍,create 方法創(chuàng)建新對(duì)象厌殉,并將其存入數(shù)據(jù)庫(kù)。
例如侈咕,User 模型中有兩個(gè)屬性公罕,name 和 occupation。調(diào)用 create 方法會(huì)創(chuàng)建一個(gè)新記錄耀销,并將其存入數(shù)據(jù)庫(kù):
user = User.create(name: "David", occupation: "Code Artist")
new 方法實(shí)例化一個(gè)新對(duì)象楼眷,但不保存:
user = User.new
user.name = "David"
user.occupation = "Code Artist"
調(diào)用 user.save 可以把記錄存入數(shù)據(jù)庫(kù)。
如果在 create 和 new 方法中使用塊,會(huì)把新創(chuàng)建的對(duì)象拉入塊中摩桶,初始化對(duì)象:
user = User.new do |u|
u.name = "David"
u.occupation = "Code Artist"
end
5-2)query查
Active Record 為讀取數(shù)據(jù)庫(kù)中的數(shù)據(jù)提供了豐富的 API桥状。
返回所有集合:
users=User.all
返回第一個(gè):
user=User.first
返回第一個(gè)名為David用戶:
davidUser = User.find_by(name:'David')
查找所有名字為David,職業(yè)為Code Artists的用戶硝清,而且按照created_at 反向排序:
users=User.find_by(name:'David', occupation:'Code Artists').order(created_at::desc)
5-3)Update更新
檢索到Active Record對(duì)象后辅斟,可以修改其屬性,然后再將其存入數(shù)據(jù)庫(kù)芦拿。
user=User.find_by(name:'David')
user.name=‘Dave’
user.save
還有種使用散列的簡(jiǎn)寫(xiě)方式士飒,指定屬性名和屬性值,例如:
user=User.find_by(name:'David')
user.update(name:'Dave')
一次更新多個(gè)屬性時(shí)使用這種方法最方便蔗崎。如果想批量更新多個(gè)記錄酵幕,可以使用類方法update_all
:
User.update_all "max_login_attempts=3, must_change_password='true'"
5-4)Delete刪除
檢索到Active Record對(duì)象后還可以將其銷毀,從數(shù)據(jù)庫(kù)中刪除缓苛。
user=User.find_by(name:'David')
user.destroy
6)數(shù)據(jù)驗(yàn)證
在存入數(shù)據(jù)庫(kù)之前芳撒,Active Record還可以驗(yàn)證模型。模型驗(yàn)證有很多方法未桥,可以檢查屬性值是否不為空笔刹,是否是唯一,沒(méi)有在數(shù)據(jù)庫(kù)中出現(xiàn)過(guò)冬耿,等等舌菜。
吧數(shù)據(jù)存入數(shù)據(jù)庫(kù)之前進(jìn)行驗(yàn)證是是否重要的步驟,所以調(diào)用save和update方法時(shí)都會(huì)做數(shù)據(jù)驗(yàn)證亦镶。驗(yàn)證失敗時(shí)返回false日月,此時(shí)不會(huì)對(duì)數(shù)據(jù)庫(kù)做任何操作。這2個(gè)方法都有對(duì)應(yīng)的爆炸方法(save!和update!)缤骨。爆炸方法要嚴(yán)格一些爱咬,如果驗(yàn)證失敗,就會(huì)拋出ActiveRecord::Recordnvalid
異常绊起。
class User < ApplicationRecord
validates :name, presence: true
end
user = User.new
user.save # => false
user.save! # => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
注意:驗(yàn)證是在寫(xiě)class的時(shí)候台颠,預(yù)定了validates
7)回調(diào)
Active Record回調(diào)用于在模型生命周期的特定時(shí)間上綁定代碼,相應(yīng)的事件發(fā)生時(shí)勒庄,執(zhí)行綁定的代碼串前。例如創(chuàng)建新記錄,更新記錄時(shí)实蔽,刪除記錄時(shí)荡碾,等等。
8)遷移
Rails提供了一個(gè)DSL(Domain-Special Language)用來(lái)處理數(shù)據(jù)庫(kù)模式局装,叫作”遷移“坛吁。
注意:什么是數(shù)據(jù)庫(kù)模式劳殖?
模式(schema)是數(shù)據(jù)庫(kù)體系結(jié)構(gòu)中的一個(gè)節(jié)點(diǎn)
對(duì)于SQL Server數(shù)據(jù)庫(kù)來(lái)說(shuō):
訪問(wèn)一個(gè)具體的表,可以由4個(gè)部分組成:
服務(wù)器名+數(shù)據(jù)庫(kù)名+模式名+表名
對(duì)于訪問(wèn)本地的數(shù)據(jù)庫(kù):
因?yàn)榉?wù)器已經(jīng)連接上了拨脉,因此不用指定
數(shù)據(jù)庫(kù)名哆姻,通過(guò)use 數(shù)據(jù)庫(kù)名 指定了
模式名,如果不指定的話玫膀,數(shù)據(jù)庫(kù)默認(rèn)使用dbo
模式
模式(schema) 是用于 在一個(gè) 大項(xiàng)目中的 各個(gè) 小項(xiàng)目
每個(gè) 小項(xiàng)目的表, 放在 各自的 模式(schema) 下面.
這樣, 遇到 小項(xiàng)目里面. 有 相同名字的 表的話, 不會(huì)發(fā)生沖突.
例如一個(gè) 公司的 系統(tǒng).
里面分2個(gè) 子系統(tǒng), 分別為 財(cái)務(wù)系統(tǒng)
和 人力資源系統(tǒng)
.
這2個(gè) 子系統(tǒng), 共用一個(gè)數(shù)據(jù)庫(kù)
那么 財(cái)務(wù)系統(tǒng)的表, 可以放在 財(cái)務(wù)的 模式(schema).
人力資源系統(tǒng)的表矛缨,放在 人力資源系統(tǒng)的模式里面。
這2個(gè) 子系統(tǒng)帖旨, 能夠 互相訪問(wèn) 對(duì)方的表
但是又不因?yàn)?表重名 的問(wèn)題箕昭,影響對(duì)方。
遷移的代碼存儲(chǔ)在特定的文件中解阅,通過(guò) rails 命令執(zhí)行落竹。可以用在 Active Record 支持的所有數(shù)據(jù)庫(kù)上货抄。下面這個(gè)遷移新建一個(gè)表:
class CreatePublications < ActiveRecord::Migration[5.0]
def change
create_table :publications do |t|
t.string :title
t.text :description
t.references :publication_type
t.integer :publisher_id
t.string :publisher_type
t.boolean :single_issue
t.timestamps
end
add_index :publications, :publication_type_id
end
end
Rails 會(huì)跟蹤哪些遷移已經(jīng)應(yīng)用到數(shù)據(jù)庫(kù)上述召,還提供了回滾功能。為了創(chuàng)建表蟹地,要執(zhí)行 rails db:migrate 命令积暖。如果想回滾,則執(zhí)行 rails db:rollback 命令锈津。
注意呀酸,上面的代碼與具體的數(shù)據(jù)庫(kù)種類無(wú)關(guān)凉蜂,可用于 MySQL琼梆、PostgreSQL、Oracle 等數(shù)據(jù)庫(kù)窿吩。
二茎杂、Active Record 數(shù)據(jù)庫(kù)遷移
遷移是 Active Record 的一個(gè)特性,允許我們按時(shí)間順序
管理數(shù)據(jù)庫(kù)模式纫雁。有了遷移煌往,就不必再用純 SQL 來(lái)修改數(shù)據(jù)庫(kù)模式,而是可以使用簡(jiǎn)單的 Ruby DSL 來(lái)描述對(duì)數(shù)據(jù)表的修改轧邪。
1)遷移概述
遷移是以一致和輕松的方式按時(shí)間順序修改數(shù)據(jù)庫(kù)模式的實(shí)用方法刽脖。它使用 Ruby DSL,因此不必手動(dòng)編寫(xiě) SQL忌愚,從而實(shí)現(xiàn)了數(shù)據(jù)庫(kù)無(wú)關(guān)的數(shù)據(jù)庫(kù)模式的創(chuàng)建和修改曲管。
我們可以把遷移看做數(shù)據(jù)庫(kù)的新“版本”。數(shù)據(jù)庫(kù)模式一開(kāi)始并不包含任何內(nèi)容硕糊,之后通過(guò)一個(gè)個(gè)遷移來(lái)添加或刪除數(shù)據(jù)表院水、字段和記錄腊徙。Active Record
知道如何沿著時(shí)間線更新數(shù)據(jù)庫(kù)模式,使其從任何歷史版本更新為最新版本檬某。Active Record
還會(huì)更新 db/schema.rb
文件撬腾,以匹配最新的數(shù)據(jù)庫(kù)結(jié)構(gòu)。
示例:
class CreateProducts < ActiveRecord::Migration[5.0]
def change
create_table :products do |t|
t.string :name
t.text :description
t.timestamps
end
end
end
這個(gè)遷移用于添加 products 數(shù)據(jù)表恢恼,數(shù)據(jù)表中包含 name 字符串字段和 description 文本字段民傻。同時(shí)隱式添加了 id 主鍵字段,這是所有 Active Record 模型的默認(rèn)主鍵厅瞎。timestamps 宏添加了 created_at 和 updated_at 兩個(gè)字段饰潜。后面這幾個(gè)特殊字段只要存在就都由 Active Record 自動(dòng)管理。
對(duì)于支持事務(wù)并提供了用于修改數(shù)據(jù)庫(kù)模式的語(yǔ)句的數(shù)據(jù)庫(kù)和簸,遷移被包裝在事務(wù)中彭雾。如果數(shù)據(jù)庫(kù)不支持事務(wù),那么當(dāng)遷移失敗時(shí)锁保,已成功的那部分操作將無(wú)法回滾薯酝。這種情況下只能手動(dòng)完成相應(yīng)的回滾操作。
某些查詢不能在事務(wù)內(nèi)部運(yùn)行爽柒。如果數(shù)據(jù)庫(kù)適配器支持 DDL 事務(wù)吴菠,就可以使用 disable_ddl_transaction! 方法在某個(gè)遷移中臨時(shí)禁用事務(wù)。
如果想在遷移中完成一些 Active Record 不知如何撤銷的操作浩村,可以使用 reversible 方法:
class ChangeProductsPrice < ActiveRecord::Migration[5.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 方法來(lái)代替 change 方法:
class ChangeProductsPrice < ActiveRecord::Migration[5.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)創(chuàng)建遷移
2-1)創(chuàng)建獨(dú)立的遷移
遷移文件儲(chǔ)存在 db/migrate 文件夾中做葵,一個(gè)遷移文件包含一個(gè)遷移類。文件名采用 YYYYMMDDHHMMSS_create_products.rb 形式心墅,即 UTC 時(shí)間戳加上下劃線再加上遷移的名稱酿矢。遷移類的名稱(駝峰式)應(yīng)該匹配文件名中遷移的名稱。例如怎燥,在 20080906120000_create_products.rb 文件中應(yīng)該定義 CreateProducts 類瘫筐,在 20080906120001_add_details_to_products.rb 文件中應(yīng)該定義 AddDetailsToProducts 類。Rails 根據(jù)文件名的時(shí)間戳部分確定要運(yùn)行的遷移和遷移運(yùn)行的順序铐姚,因此當(dāng)需要把遷移文件復(fù)制到其他 Rails 應(yīng)用策肝,或者自己生成遷移文件時(shí),一定要注意遷移運(yùn)行的順序隐绵。
當(dāng)然之众,計(jì)算時(shí)間戳不是什么有趣的事,因此 Active Record 提供了生成器:
$ bin/rails generate migration AddPartNumberToProducts
上面的命令會(huì)創(chuàng)建空的遷移依许,并進(jìn)行適當(dāng)命名:
class AddPartNumberToProducts < ActiveRecord::Migration[5.0]
def change
end
end
2-2)模型生成器
模型和腳手架生成器會(huì)生成適用于添加新模型的遷移棺禾。這些遷移中已經(jīng)包含用于創(chuàng)建有關(guān)數(shù)據(jù)表的指令。如果我們告訴 Rails 想要哪些字段悍手,那么添加這些字段所需的語(yǔ)句也會(huì)被創(chuàng)建帘睦。例如袍患,運(yùn)行下面的命令:
$ bin/rails generate model Product name:string description:text
上面的命令會(huì)創(chuàng)建下面的遷移:
class CreateProducts < ActiveRecord::Migration[5.0]
def change
create_table :products do |t|
t.string :name
t.text :description
t.timestamps
end
end
end
我們可以根據(jù)需要添加“字段名稱/類型”對(duì),沒(méi)有數(shù)量限制竣付。
2-3)傳遞修飾符
可以直接在命令行
中傳遞常用的類型修飾符
诡延。這些類型修飾符用大括號(hào)括起來(lái),放在字段類型之后古胆。例如肆良,運(yùn)行下面的命令:
$ bin/rails generate migration AddDetailsToProducts 'price:decimal{5,2}' supplier:references{polymorphic}
上面的命令會(huì)創(chuàng)建下面的遷移:
class AddDetailsToProducts < ActiveRecord::Migration[5.0]
def change
add_column :products, :price, :decimal, precision: 5, scale: 2
add_reference :products, :supplier, polymorphic: true, index: true
end
end
3)編寫(xiě)遷移
使用生成器創(chuàng)建遷移后,就可以開(kāi)始寫(xiě)代碼了逸绎。
3-1)創(chuàng)建數(shù)據(jù)表
create_table
方法是最基礎(chǔ)惹恃、最常用的方法,其代碼通常是由模型或腳手架生成器生成的棺牧。典型的用法像下面這樣:
create_table :products do |t|
t.string :name
end
上面的命令會(huì)創(chuàng)建包含 name 字段的 products 數(shù)據(jù)表(后面會(huì)介紹巫糙,數(shù)據(jù)表還包含自動(dòng)創(chuàng)建的 id 字段)。
默認(rèn)情況下颊乘,create_table 方法會(huì)創(chuàng)建 id 主鍵参淹。可以用 :primary_key 選項(xiàng)來(lái)修改主鍵名稱乏悄,還可以傳入 id: false 選項(xiàng)以禁用主鍵浙值。如果需要傳遞數(shù)據(jù)庫(kù)特有的選項(xiàng),可以在 :options 選項(xiàng)中使用 SQL 代碼片段檩小。例如:
create_table :products, options: "ENGINE=BLACKHOLE" do |t|
t.string :name, null: false
end
上面的代碼會(huì)在用于創(chuàng)建數(shù)據(jù)表的 SQL 語(yǔ)句末尾加上 ENGINE=BLACKHOLE(如果使用 MySQL 或 MarialDB开呐,默認(rèn)選項(xiàng)是 ENGINE=InnoDB)。
還可以傳遞帶有數(shù)據(jù)表描述信息的 :comment 選項(xiàng)规求,這些注釋會(huì)被儲(chǔ)存在數(shù)據(jù)庫(kù)中筐付,可以使用 MySQL Workbench、PgAdmin III 等數(shù)據(jù)庫(kù)管理工具查看颓哮。對(duì)于大型數(shù)據(jù)庫(kù)家妆,強(qiáng)列推薦在應(yīng)用的遷移中添加注釋鸵荠。目前只有 MySQL 和 PostgreSQL 適配器支持注釋功能冕茅。
3-2)創(chuàng)建聯(lián)結(jié)數(shù)據(jù)表
create_join_table 方法用于創(chuàng)建 HABTM(has and belongs to many)聯(lián)結(jié)數(shù)據(jù)表。典型的用法像下面這樣:
create_join_table :products, :categories
上面的代碼會(huì)創(chuàng)建包含 category_id 和 product_id 字段的 categories_products 數(shù)據(jù)表蛹找。這兩個(gè)字段的 :null 選項(xiàng)默認(rèn)設(shè)置為 false姨伤,可以通過(guò) :column_options 選項(xiàng)覆蓋這一設(shè)置:
create_join_table :products, :categories, column_options: { null: true }
聯(lián)結(jié)數(shù)據(jù)表的名稱默認(rèn)由 create_join_table 方法的前兩個(gè)參數(shù)按字母順序組合而來(lái)∮辜玻可以傳入 :table_name 選項(xiàng)來(lái)自定義聯(lián)結(jié)數(shù)據(jù)表的名稱:
create_join_table :products, :categories, table_name: :categorization
上面的代碼會(huì)創(chuàng)建 categorization 數(shù)據(jù)表乍楚。
create_join_table 方法也接受塊作為參數(shù),用于添加索引(默認(rèn)未創(chuàng)建的索引)或附加字段:
create_join_table :products, :categories do |t|
t.index :product_id
t.index :category_id
end