也許你已經注意到了,在我們前面的代碼中,數據庫定義裡都使用了一個integer型的字段id作為主鍵,這是Active Record的一個約定。
或許你要問,為什麼不用訂單編號或者某個有意義的列來作為主鍵呢?使用id作為主鍵有一個很重要的原因,就是如果使用具有內在格式的主鍵的話,隨著時間推移,有可能其中的規則也會變化。例如,使用ISBN號碼來給book表做主鍵,畢竟ISBN號碼是唯一的,但是,有可能當一本書寫完後,美國的出版業已經發展了並且在所有的ISBN號碼後又附加了一位數字。
如果我們使用了ISBN作為book表的主鍵,我們就要更新所有book表的記錄來反映這個變化,而且還有一個問題,還有其他表引用了book表的主鍵,我們就要更新所有的引用,這還牽涉到要刪除外鍵,所有的這一切都是非常痛苦的。
如果使用有意義的值作為主鍵,那麼我們將收到外界業務規則的影響,如果使用id,我們可以自己完全控制,而且如果象ISBN等一些東西改變的話,將不會影響到數據庫結構。
如果你從一個新的數據庫結構開始,可能會遵循約定,給所有的表都使用id作為主鍵,但是,當你使用的是一個既存的數據庫開始的時候,Active Record提供了簡單的方法來讓你重新給表指定主鍵,例如:
class BadBook < ActiveRecord::Base set_primary_key "isbn" end
通常,Active Record會注意給新創建的記錄生成主鍵值-使用自增長的整數。不管怎樣,當你override表的主鍵名字的時候,你就需要自己負責給新建記錄一個唯一的主鍵值。也許有些讓人驚訝,你還是設置一個id的屬性來完成這件事,因為Active Record所關心的是,主鍵的設置永遠都使用名為id屬性,set_primary_key的聲明只是設置了使用的列名,下面的例子,我們使用ISBN作為主鍵。
book = BadBook.new book.id = "0-12345-6789" book.title = "My Great American Novel" book.save # ... book = BadBook.find("0-12345-6789") puts book.title # => "My Great American Novel" p book.attributes #=> {"isbn" =>"0-12345-6789", "title"=>"My Great American Novel"}
也就是說,在設置主鍵的時候,使用id屬性,其他時候,使用真實的列名。