在前文《Ruby on Rails,創建和執行migrations遷移文件》中我們提到過創建模型的事情,我們創建模型的同時生成遷移文件。那時候我們關注的是遷移文件,現在我們把目光投向模型這邊。
創建模型的命令是
rails generate model ModelNameInCamelCase
其中最后一個參數是模型的名字,用每個單詞首字母大寫的格式,比如說rails generate model Subject。
這個操作會生成兩個中要的文件,其一是位於db/migrate目錄下的遷移文件,“20120901143244_create_subjects.rb”。打開這個文件看看,會發現其實這里面定義的是一個叫做CreateSubjects的類,繼承ActiveRecord::Migration,創建一個叫做subjects的表。
class CreateSubjects < ActiveRecord::Migration def change create_table :subjects do |t| t.timestamps end end end
另一個是位於app/model下的subject.rb,注意到是單數。打開文件看一看,其中定義了一個叫做Subject的類,繼承ActiveRecord::Base,沒有任何其他的內容。這代表着,Subject類打算完全按照ActiveRecord提供的缺省行為運行,這個后面再講。
注意這些生成文件的位置、文件名、內容可以看出他們之間有着一致性(都基於模型名Subject)。
db/migrate
文件名:20120901143244_create_subjects.rb
類名:CreateSubjects
繼承:ActiveRecord::Migration
表名:subjects
app/models
文件名:subject.rb
類名:Subject
繼承:ActiveRecord::Base
而如果我們遵守這樣的一致性便能保證Rails能夠建立他們之間的關系,即使不對這些文件的關系進行更多的配置。比如說在某個時刻我對Rails說:“我要使用Subject類!”。你猜怎么着,Rails就會嘗試着到app/models中名為subject.rb文件中找到Subject類的定義。如果我們說:”Subject類,我需要從數據庫中讀取對象!“。Subject類看了看自己,說沒問題,我是一個ActiveRecord所以我知道應該到數據庫中找到一張叫subjects的表,並從中讀取出相應的對象。
當然了,這種遵守不是必須的,但如果我們簡單的遵守規則能夠這么方便快捷,有什么理由不這么做呢?
所以說rails generate命令沒有什么神秘的,只是幫我們按照約定生成代碼而已。我們也可以按照約定自己來編寫這些內容,結果不會有任何區別。使用rails generate方法創建出來的模型都自動繼承了ActiveRecord,相當於建立了與數據庫的關聯,如果只想建立一個普通的類並不與數據庫關聯,刪除”<ActiveRecord::Basde“或者手工創建即可。
回過頭看一看User類,在app/models目錄中,以后模型都在這個目錄里放着。這個類創建之后,在《Ruby on Rails,數據庫遷移命令和遷移任務編寫》中修改過遷移文件。
class AlterUsers < ActiveRecord::Migration def up rename_table("users","admin_users") add_column("admin_users","username",:string,:limit=>25) add_column("admin_users","email",:string,:limit=>50) change_column("admin_users","email",:string,:default=>"",:limit=>100) add_column("admin_users","password",:string,:limit=>25) rename_column("admin_users","password","hashed_password") add_column("admin_users","salt",:string,:limit=>40) puts "***about to add an index ***" add_index("admin_users","username") end def down remove_index("admin_users","username") remove_column("admin_users","salt") rename_column("admin_users","hashed_password","password") remove_column("admin_users","password") remove_column("admin_users","email") remove_column("admin_users","username") rename_table("admin_users","users") end end
靠上面的位置,我們使用rename_table命令將表名從users改為了admin_users。可是請注意,遷移文件的這些操作,模型文件並不知道。換句話說,User依然以為與自己關聯的表叫做users,但很顯然現在已經不是了。
rename_table("users","admin_users")
這樣一來就違背了Rails的規則,實際工作中是有可能出現這種情況的。比如說擺在我們面前的是一個老系統,不能按照我們的要求修改表名。我們來嘗試自我修復一下,有兩種方法。
第一種是調用ActiveRecord中內建的set_table_name方法,告訴User類與你對應的表名從現在起是admin_users了。第二種方法是將User類名改為AdminUser,文件名改為admin_user。