Rails開發細節《七》ActiveRecord Associations關聯
1.為什么需要關聯
很多時候,比如說電子商務中的用戶和訂單,一個用戶會有很多的訂單,一個訂單只屬于一個用戶,這就是一種關聯。
在創建訂單的時候需要用戶主鍵作為外鍵,刪除用戶的的同時需要刪除用戶的訂單。
在rails中可以向下面這樣訂單關聯。
class?Customer?<?ActiveRecord::Base???has_many?:orders,?:dependent?=>?:destroy?end???class?Order?<?ActiveRecord::Base???belongs_to?:customer?end?就可以像下面這樣創建訂單,刪除用戶。
@order?=?@customer.orders.create(:order_date?=>?Time.now)??@customer.destroy?2.關聯的類型
有下面6中關聯。
- belongs_to
- has_one
- has_many
- has_many :through
- has_one :through
- has_and_belongs_to_many
?
2.1.belongs_to
belongs_to是一種一對一的關聯。表達一種屬于的關系。
就像一個訂單只能屬于個用戶。在訂單表會有一個字段存儲用戶主鍵,這個字段是訂單表的外鍵。
?
class?Order?<?ActiveRecord::Base???belongs_to?:customer?end?2.2.has_one
has_one也是一種一對一的關聯。表達一種有一個的關系。
就像一個供應商只能有一個賬戶。賬戶表有一個供應商主鍵,是賬戶表的外鍵。
?
class?Supplier?<?ActiveRecord::Base???has_one?:account?end?2.3.has_many
has_many是一種一對多的關聯。表達有多個的關系。
就像一個用戶有多個訂單。
?
class?Customer?<?ActiveRecord::Base???has_many?:orders?end?has_many關聯的名稱需要使用復數形式。
2.4.has_many :through
has_many是一種多對多的關聯。存在一個中間的model。是通過中間model建立關聯。
有一個場景就是病人看病,但是需要和醫生進行預約。一個醫生會有多個預約記錄,一個病人也會有多個預約記錄。在預約表中會有醫生主鍵和病人主鍵。
class?Physician?<?ActiveRecord::Base???has_many?:appointments???has_many?:patients,?:through?=>?:appointments?end???class?Appointment?<?ActiveRecord::Base???belongs_to?:physician???belongs_to?:patient?end???class?Patient?<?ActiveRecord::Base???has_many?:appointments???has_many?:physicians,?:through?=>?:appointments?end??
?其實就是把醫生和病人的預約關系單獨表存放,這張表也會有主鍵。
?
class?Document?<?ActiveRecord::Base???has_many?:sections???has_many?:paragraphs,?:through?=>?:sections?end???class?Section?<?ActiveRecord::Base???belongs_to?:document???has_many?:paragraphs?end???class?Paragraph?<?ActiveRecord::Base???belongs_to?:section?end?2.5.has_one :through
?
class?Supplier?<?ActiveRecord::Base???has_one?:account???has_one?:account_history,?:through?=>?:account?end???class?Account?<?ActiveRecord::Base???belongs_to?:supplier???has_one?:account_history?end???class?AccountHistory?<?ActiveRecord::Base???belongs_to?:account?end?2.6.has_and_belongs_to_many
has_and_belongs_to_many也是一種多對多的關聯。不存在一個中間的model。關系在單獨的表中存放,但是這張表沒有單獨的id,只有雙方的id。
?
class?Assembly?<?ActiveRecord::Base???has_and_belongs_to_many?:parts?end???class?Part?<?ActiveRecord::Base???has_and_belongs_to_many?:assemblies?end?2.7.選擇belongs_to還是has_one
belongs_to一般放在有外鍵的model中,表達一種屬于的關系。has_one表達一種擁有的關系。
?
class?Supplier?<?ActiveRecord::Base???has_one?:account?end???class?Account?<?ActiveRecord::Base???belongs_to?:supplier?end?供應商有一個賬號,一個賬號屬于供應商。
2.8.選擇has_many :through還是has_and_belongs_to_many
如果你需要關系model作為獨立的實體,就選擇has_many :through;不需要獨立的實體就選擇has_and_belongs_to_many。
?
class?Assembly?<?ActiveRecord::Base???has_and_belongs_to_many?:parts?end???class?Part?<?ActiveRecord::Base???has_and_belongs_to_many?:assemblies?end??
class?Assembly?<?ActiveRecord::Base???has_many?:manifests???has_many?:parts,?:through?=>?:manifests?end???class?Manifest?<?ActiveRecord::Base???belongs_to?:assembly???belongs_to?:part?end???class?Part?<?ActiveRecord::Base???has_many?:manifests???has_many?:assemblies,?:through?=>?:manifests?end?如果在連接實體上需要驗證,回調,或者額外的屬性,那就需要使用has_many :through。
2.9.polymorphic
使用polymorphic關聯,一個model可以多個model。
就像圖片model,既屬于員工model,也屬于產品model。就是說員工和產品都有圖片,他們共享同一個圖片model。
?
class?Picture?<?ActiveRecord::Base???belongs_to?:imageable,?:polymorphic?=>?true?end???class?Employee?<?ActiveRecord::Base???has_many?:pictures,?:as?=>?:imageable?end???class?Product?<?ActiveRecord::Base???has_many?:pictures,?:as?=>?:imageable?end??
class?CreatePictures?<?ActiveRecord::Migration???def?change?????create_table?:pictures?do?|t|???????t.string??:name???????t.integer?:imageable_id???????t.string??:imageable_type???????t.timestamps?????end???end?end??
class?CreatePictures?<?ActiveRecord::Migration???def?change?????create_table?:pictures?do?|t|???????t.string?:name???????t.references?:imageable,?:polymorphic?=>?true???????t.timestamps?????end???end?end?2.10.自連接
有時候,實體會連接自己。
就好比員工表,有些員工同時又是經理,會領導一部分的員工,這樣就會造成自連接。
?
class?Employee?<?ActiveRecord::Base???has_many?:subordinates,?:class_name?=>?"Employee",?????:foreign_key?=>?"manager_id"???belongs_to?:manager,?:class_name?=>?"Employee"?end??
本文轉自 virusswb 51CTO博客,原文鏈接:http://blog.51cto.com/virusswb/1019921,如需轉載請自行聯系原作者
總結
以上是生活随笔為你收集整理的Rails开发细节《七》ActiveRecord Associations关联的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。