railsapi跨越邊界Rails遷移_第1頁
railsapi跨越邊界Rails遷移_第2頁
railsapi跨越邊界Rails遷移_第3頁
railsapi跨越邊界Rails遷移_第4頁
railsapi跨越邊界Rails遷移_第5頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、.rails api 跨越邊界 Rails 遷移rails api,跨越邊界:Rails遷移2006年9月25日Ruby onRails是不斷開展的Web開發(fā)框架,它實(shí)現(xiàn)了一些先進(jìn)的想法,例如通過配置進(jìn)展約定、大量的元編程、特定于域的語言以及用數(shù)據(jù)庫包裝代替對象關(guān)系映射。這篇文章研究的Rails形式遷移是一種把每個(gè)數(shù)據(jù)庫的形式變化與根本對象模型別離的思想。作為喜歡冒險(xiǎn)的摩托車手,我關(guān)注兩個(gè)嚴(yán)肅的社區(qū):山地摩托車手和公路摩托車手。常規(guī)的看法是山地摩托車手更危險(xiǎn),但我并不同意。公路摩托手必須考慮要比石頭和樹危險(xiǎn)得多的障礙:汽車。類似的異議也出如今面向?qū)ο髴?yīng)用程序開發(fā)使用的兩個(gè)持久性策略之間。目前,

2、持久性框架使用兩種方法中的一種:映射或包裝。映射解決方案允許創(chuàng)立獨(dú)立的數(shù)據(jù)庫形式和對象模型,然后用一個(gè)軟件層來管理兩者間的差異。映射解決方案試圖構(gòu)建一個(gè)與數(shù)據(jù)庫形式的構(gòu)造非常相似的對象模型。與之相反,包裝解決方案用對象作為數(shù)據(jù)庫表和行的包裝器來操縱數(shù)據(jù)庫中的數(shù)據(jù)。常規(guī)的想法認(rèn)為在解決方案發(fā)布之后,映射解決方案通常更靈敏,因?yàn)橛成滠浖梢愿玫靥幚硇问交驅(qū)ο竽P椭械淖兓?。但是這個(gè)想法忽略了其中最重要的部分:數(shù)據(jù)。要有效地管理涉及持久性域模型的應(yīng)用程序變化,必須協(xié)調(diào)數(shù)據(jù)、形式和模型的變化。大多數(shù)工程團(tuán)隊(duì)做不到這一點(diǎn)。開發(fā)團(tuán)隊(duì)處理形式變化時(shí),通常會(huì)用SQL腳本從頭開場生成一個(gè)新版形式。腳本可能會(huì)刪除

3、所有的表,再添加所有的表。這樣的策略會(huì)破壞所有測試數(shù)據(jù),因此對于消費(fèi)場景來說毫無價(jià)值。偶爾,工具可能會(huì)創(chuàng)立腳本,由腳本生成delta形式,或者生成使用alter_table這樣的SQL命令修改以前版本的形式。但是很少有團(tuán)隊(duì)會(huì)費(fèi)力氣創(chuàng)立能取消形式變化的腳本,而且成功地創(chuàng)立了處理數(shù)據(jù)變化的自動(dòng)腳本的團(tuán)隊(duì)更少。簡而言之,傳統(tǒng)的映射策略忽略公路上的汽車:回退壞的形式變化并處理數(shù)據(jù)。關(guān)于這個(gè)系列在跨越邊界系列中,作者Bruce Tate倡導(dǎo)這樣一個(gè)概念:今天的Java程序員可以通過學(xué)習(xí)其他方式和語言而受益。在編程領(lǐng)域中,Java技術(shù)是所有開發(fā)工程的最正確選擇的情況已經(jīng)變了。其他框架正在影響Java框架的

4、構(gòu)建方式,從其他語言學(xué)到的概念有助于Java編程。編寫的Python或Ruby、Smalltalk等等代碼可以改變Java編碼的方式。這個(gè)系列介紹了與Java開發(fā)有根本不同,但是卻直接適用于Java開發(fā)的編程概念和技術(shù)。在某些情況下,需要集成這些技術(shù)以利用它們。在其他情況下,可以直接應(yīng)用這些概念。其他語言和框架可以影響Java社區(qū)的開發(fā)人員、框架甚至根本方式,與此相比,單獨(dú)的工具并不那么重要。這篇文章深化研究了Ruby onRails遷移-Rails處理消費(fèi)數(shù)據(jù)庫變化的解決方案。遷移用包裝的方式組合了協(xié)調(diào)形式變化和數(shù)據(jù)變化的威力和簡單性。假設(shè)以前沒有學(xué)習(xí)過活動(dòng)記錄-Rails底層的持久性層,我

5、建議您先閱讀跨越邊界系列中以前的這篇Rails文章。在Java編程中處理形式變化基于映射的框架需要形式、模型和映射。這樣的框架是重復(fù)性的。請想像一下指定一個(gè)屬性需要重復(fù)多少次:模型中的getter模型中的setter模型中的實(shí)例變量映射的"to"端映射的"from"端列定義公平地講,Hibernate這樣的Java框架通過代碼生成的方式消除了不少重復(fù)工作。對象關(guān)系映射器可以處理遺留形式,對于新的數(shù)據(jù)庫形式,可以用Hibernate提供的工具直接從模型生成形式并用IDE生成getter和setter??梢杂肑ava標(biāo)注把映射嵌入域模型,但是按我的觀點(diǎn),這在

6、一定程度上違犯了使用映射的初衷。這種代碼生成技術(shù)還有另一個(gè)用處:形式遷移。有些代碼生成工具可以發(fā)現(xiàn)新的域模型和舊的形式之間的區(qū)別,并生成溝通這些不同的SQL腳本。請記住這些腳本處理的是形式,而不是數(shù)據(jù)。例如,考慮這樣一個(gè)遷移:把first_name和last_name這兩個(gè)數(shù)據(jù)庫列合并成叫作name的單一列。來自典型Java持久性框架的工具對數(shù)據(jù)庫管理員沒有幫助,因?yàn)檫@些工具只處理問題的一部分:形式中的變化。在進(jìn)展這個(gè)形式變化時(shí),還需要可以處理現(xiàn)有數(shù)據(jù)。在需要部署這個(gè)假想應(yīng)用程序的新版本時(shí),數(shù)據(jù)庫管理員通常必須手工創(chuàng)立SQL腳本來完成以下工作:創(chuàng)立叫作name的新列。把first_name和l

7、ast_name的數(shù)據(jù)放到新列中。刪除first_name和last_name列。假設(shè)造成形式變化的代碼版本仍然處在不完善的狀態(tài),那么經(jīng)常必須手工回退變化。只有很少的團(tuán)隊(duì)有這個(gè)素養(yǎng)可以集成并自動(dòng)進(jìn)展跨模型、形式和數(shù)據(jù)的變化。Rails遷移根底在Rails中,所有形式變化-包括形式最初的創(chuàng)立-都在遷移中發(fā)生。數(shù)據(jù)庫形式中的每個(gè)變化都有自己的遷移對象,遷移對象包裝了前進(jìn)和后退。清單1顯示了一個(gè)空遷移:我很快將介紹如何調(diào)用遷移,但是如今請看看清單1中的遷移構(gòu)造。在這個(gè)遷移的up方法中,要放置進(jìn)展一個(gè)邏輯數(shù)據(jù)庫變化所需的全部代碼。還要捕獲任何變化,從而可以取消形式變化。通過封裝up和down,Rail

8、s開發(fā)和消費(fèi)工具可以自動(dòng)進(jìn)展涉及持久性對象模型的變化的部署和回退過程。這些數(shù)據(jù)庫變化可能包括:通過封裝up和down方法,Rails開發(fā)和消費(fèi)工具可以自動(dòng)進(jìn)展涉及持久性對象模型的變化的部署和回退過程。添加或刪除新表。添加或刪除新列。以其他方式修改數(shù)據(jù)庫,包括添加、刪除或修改索引或其他約束。修改數(shù)據(jù)庫數(shù)據(jù)。通過允許改變數(shù)據(jù),遷移大大簡化了相關(guān)數(shù)據(jù)和形式的變化的同步過程。例如,可以添加一個(gè)查詢表,把每個(gè)州和州的兩位數(shù)字ZIP代碼關(guān)聯(lián)起來。在遷移中,可以填充數(shù)據(jù)庫表,可能通過調(diào)用SQL腳本或裝載fixture。假設(shè)遷移正確,那么每個(gè)遷移都會(huì)把數(shù)據(jù)庫置于一個(gè)一致的狀態(tài),不需要手工干預(yù)。每個(gè)遷移的文件名

9、都以一個(gè)惟一的編號開頭。這個(gè)約定讓Rails可以對遷移實(shí)現(xiàn)很強(qiáng)的排序。用這個(gè)策略,可以前后轉(zhuǎn)移到邏輯數(shù)據(jù)庫形式的任何狀態(tài)。使用遷移要使用遷移,只需要一個(gè)Rails工程和一個(gè)數(shù)據(jù)庫。假設(shè)想試驗(yàn)這里的代碼,請安裝一個(gè)關(guān)系數(shù)據(jù)庫管理器、Ruby和Rails1.1以上版本。就可以開場了。請按以下步驟創(chuàng)立數(shù)據(jù)庫支持的Rails工程:輸入railsblog,創(chuàng)立叫作blog的Rails工程。創(chuàng)立叫作blog_development的數(shù)據(jù)庫。假設(shè)使用MySQL,只需在MySQL命令行上輸入create database blog_development。通過config/database.yml對數(shù)據(jù)庫做必

10、要的配置,添加數(shù)據(jù)庫登錄ID和口令。要查看編號的工作方式,請生成一個(gè)遷移:在blog目錄,輸入ruby script/generate migration create_blog。假設(shè)正在運(yùn)行Unix,可以省略ruby。從如今起我就省略它。輸入script/generate migration create_user。請看看blog/db/migrate中的文件,會(huì)看到兩個(gè)順序編號的文件。遷移生成器負(fù)責(zé)管理編號。刪除叫作001_create_blog.rb的遷移,并用script/generate migration create_blog重新創(chuàng)立它??梢宰⒁獾?,新創(chuàng)立的遷移是003_crea

11、te_blog.rb,如清單2所示:cd blog script/generate migration create_blog create db/migrate create db/migrate/001_create_blog.rb script/generate migration create_user exists db/migrate create db/migrate/002_create_user.rb ls db/migrate/001_create_blog.rb 002_create_user.rb rm db/migrate/001_create_blog.rb scr

12、ipt/generate migration create_blog exists db/migrate create db/migrate/003_create_blog.rb ls db/migrate/002_create_user.rb 003_create_blog.rb可以看到每個(gè)遷移的數(shù)字前綴。新遷移的編號是目錄中的最大前綴加1。這個(gè)策略保證了遷移按順序生成并執(zhí)行。在其他遷移的結(jié)果之上構(gòu)建的遷移例如一個(gè)遷移要向其他遷移創(chuàng)立的表中添加一列會(huì)保持一致。編號機(jī)制簡單、直觀而一致。要查看遷移在數(shù)據(jù)庫中的工作方式,請刪除db/migrations目錄中的全部遷移。輸入script/gene

13、rate model Article,生成Article的模型對象以及與清單1中的遷移類似的空遷移。請注意,Rails為每篇文章生成了模型對象和遷移。請把db/migrate/001_create_articles.rb編輯成清單3這樣:前后遷移要準(zhǔn)確地看到遷移做的工作,只需運(yùn)行遷移并查看數(shù)據(jù)庫。在blog目錄中,輸入rake migrate。rake是Ruby上與C平臺的make或Java平臺的ant等價(jià)的東西。migrate是一個(gè)rake任務(wù)。接下來,顯示數(shù)據(jù)庫中的表。假設(shè)使用MySQL,只需進(jìn)入mysql命令提示符,輸入use blog_development;,然后輸入show tab

14、le;,就可以看到清單4的結(jié)果:請注意第二個(gè)表:schema_info。我的遷移指定了articles表,但是rake migrate命令自動(dòng)創(chuàng)立了schema_info。請執(zhí)行select*from schema_info。不帶參數(shù)運(yùn)行rake migrate時(shí),就是要求Rails運(yùn)行所有還沒有應(yīng)用的遷移。Rails做以下工作:假設(shè)schema_info表還不存在,就創(chuàng)立這個(gè)表。假設(shè)schema_info中沒有行,就用值0插入一行。運(yùn)行編號大于當(dāng)前遷移的所有遷移的up方法。rake通過讀取schema_info表中version列的值,判斷當(dāng)前遷移的編號。rake按照編號從小到大運(yùn)行up遷移

15、,從大到小運(yùn)行down遷移。要向下遷移,只要帶著版本號運(yùn)行rake migrate即可。向下遷移會(huì)破壞數(shù)據(jù),所以要小心。有些操作例如刪除表或列也會(huì)破壞數(shù)據(jù)。清單5顯示了向下遷移然后回退的結(jié)果??梢钥吹絪chema_info忠實(shí)地跟蹤當(dāng)前版本號。這種方式完成了一項(xiàng)精彩的工作:允許在代表不同開發(fā)階段的形式之間平滑地挪動(dòng)。rake migrate VERSION=0in/Users/batate/rails/blog=CreateArticles:reverting=-drop_table:articles-0.1320 s=CreateArticles:reverted0.1322 s=mysql

16、-u root blog_development;mysql show tables;+-+|Tables_in_blog_development|+-+|schema_info|+-+1 row in set0.00 secmysql select*from schema_info;+-+|version|+-+|0|+-+1 row in set0.00 secmysql exit Bye rake migratein/Users/batate/rails/blog=CreateArticles:migrating=-create_table:articles-0.0879 s=Creat

17、eArticles:migrated0.0881 s=mysql-u root blog_development;mysql select*from schema_info;+-+|version|+-+|1|+-+1 row in set0.00 sec如今要翻開表本身了。請看清單3和表定義。假設(shè)使用MySQL,可以執(zhí)行show create table articles;命令,生成清單6的結(jié)果:mysql show create table articles;+-+.-+|Table|Create Table|+-+.-+|articles|CREATE TABLE'article

18、s''id'int11NOT NULL auto_increment,'name'varchar80default NULL,'author'varchar40default NULL,'body'text,'created_on'datetime default NULL,PRIMARY KEY'id'ENGINE=InnoDB DEFAULT CHARSET=latin1|+-+.-+1 row in set0.00 sec可以看到,這個(gè)表定義的大部分都直接來自遷移。Rails遷移的一個(gè)

19、核心優(yōu)勢就是不需要使用直接的SQL語法來創(chuàng)立表。由于在Ruby中處理每個(gè)形式修改,所以生成的SQL是獨(dú)立于數(shù)據(jù)庫的。但是請注意id列。雖然沒有指定這個(gè)列,但是Rails遷移會(huì)自動(dòng)創(chuàng)立它,并具有auto_increment和NOT NULL屬性。具有這個(gè)特殊列定義的id列符合Rails標(biāo)識符列的標(biāo)準(zhǔn)。假設(shè)想創(chuàng)立這個(gè)表,但不要id,遷移只需添加:id選項(xiàng),如清單7的遷移所示:如今已經(jīng)深化研究了單一遷移,但是還沒有在形式中進(jìn)展變化。如今要?jiǎng)?chuàng)立另一個(gè)表,這次是用于評論的表。請輸入script/generate model Comment生成叫作Comment的模型。把db/migrate/002_cr

20、eate_comments.rb生成的遷移編輯成像清單8一樣。還需要一個(gè)有幾個(gè)列的新表,還要利用Rails的功能添加非空列和默認(rèn)值。運(yùn)行這個(gè)遷移。假設(shè)在遷移過程中出錯(cuò),只要記住遷移的工作方式即可。需要檢查schema_info表中行的值,并查看數(shù)據(jù)庫的狀態(tài)。在糾正代碼之后,可能需要手工刪除某些表,或者修改schema_info中行的值。請記住,并沒有發(fā)生什么魔術(shù)。Rails運(yùn)行所有還沒運(yùn)行的遷移上的up方法。假設(shè)要添加的表或列已經(jīng)存在,那么操作就會(huì)失敗,所以需要確保遷移在一致的狀態(tài)下運(yùn)行。至于如今,請運(yùn)行rake migrate。清單9顯示了結(jié)果:遷移可以處理許多不同類型的形式變化。可以添加和

21、刪除索引;通過刪除、改名或添加列來修改表;甚至在必要的時(shí)候借助于SQL。用SQL能做什么,用遷移就能做什么。Rails對大多數(shù)常見操作都有包裝器,包括:創(chuàng)立表create_table刪除表drop_table向表中添加列add_column從表中刪除列remove_column給列改名rename_column修改列change_column創(chuàng)立索引create_index刪除索引drop_index有些遷移修改不只一個(gè)列,形成數(shù)據(jù)庫中單一的邏輯變化。請考慮這個(gè)遷移:添加頂級blog,帶有屬于這個(gè)blog的文章。需要?jiǎng)?chuàng)立一個(gè)新表,還要添加指向blog的每個(gè)文章的外鍵。清單10顯示了完好的遷移。

22、可以輸入rake migrate來運(yùn)行遷移。還有數(shù)據(jù)用SQL能做什么,用遷移就能做什么。迄今為止,我只把重點(diǎn)放在形式的變化上,但是數(shù)據(jù)的變化也是重要的。有些數(shù)據(jù)庫變化要求數(shù)據(jù)和形式一起變化,有些數(shù)據(jù)變化要求邏輯變化。例如,假設(shè)想為每篇blog文章創(chuàng)立一個(gè)新評論,說明文章是對評論開放的。假設(shè)在blog已經(jīng)開放一段時(shí)間之后才施行這個(gè)變化,那么希望只對還沒有評論的文章添加新評論。用遷移可以容易地進(jìn)展這個(gè)變化,因?yàn)檫w移可以訪問對象模型并根據(jù)模型的狀態(tài)進(jìn)展決策。請輸入script/generate migration add_open_for_comments。需要對評論進(jìn)展修改,捕捉belongs_t

23、o關(guān)系,并編寫新的遷移。清單11顯示了模型對象和新的遷移:對于清單11中的遷移,做了個(gè)戰(zhàn)術(shù)性決策。它認(rèn)定用戶在參加之后不想看到歡送信息消失,所以選擇向下遷移時(shí)不刪除任何記錄。在遷移中解決數(shù)據(jù)變化的才能是個(gè)強(qiáng)大的工具??梢酝綌?shù)據(jù)和形式中的變化,也可以解決涉及對模型對象進(jìn)展邏輯操作的數(shù)據(jù)變化。我已經(jīng)演示了遷移中能做的大部分工作。還可以利用其他一些工具。假設(shè)想對現(xiàn)有數(shù)據(jù)庫使用遷移,可以用rake schema_dump對如今的形式做個(gè)快照。這個(gè)rake任務(wù)在db/schema.rb中用正確的遷移語法創(chuàng)立Ruby形式。然后可以生成遷移,并把導(dǎo)出的形式拷貝進(jìn)遷移。請參閱參考資料獲得更多細(xì)節(jié)。我沒有談到

24、測試fixture,在設(shè)置測試數(shù)據(jù)或填充數(shù)據(jù)庫時(shí)它們會(huì)很有幫助。請參閱跨越邊界系列中以前關(guān)于單元測試的文章獲得更多細(xì)節(jié)。最終比較Java編程的遷移方案并不強(qiáng)壯。有些產(chǎn)品對于有些形式遷移問題有針對性強(qiáng)的解決方案,但是沒有協(xié)調(diào)形式變化的系統(tǒng)化過程-包括前進(jìn)和后退-處理數(shù)據(jù)和對象模型中的變化會(huì)是項(xiàng)困難的任務(wù)。Rails解決方案有一些核心優(yōu)勢:Rails遷移是DRY的不重復(fù)你自己。使用Rails時(shí),只要準(zhǔn)確地指定每個(gè)列的定義一次。其他一些映射器要求指定一個(gè)列六次:在形式、getter、setter、模型的實(shí)例變量、"from"映射和"to"映射中。Rails遷移

25、既支持?jǐn)?shù)據(jù)遷移,也支持形式遷移。Rails遷移支持把模型邏輯用于數(shù)據(jù)遷移,而SQL腳本做不到這一點(diǎn)。Rails遷移獨(dú)立于數(shù)據(jù)庫,但SQL腳本不獨(dú)立。Rails遷移允許對不支持的擴(kuò)展例如存儲過程或約束直接使用SQL,而有些ORM映射器不支持。遷移有這么多好處,您可能以為會(huì)有復(fù)雜的代碼段,但實(shí)際上它們出奇的簡單。遷移具備有意義的名稱和版本編號。每個(gè)遷移都有up和down方法。最后,rake協(xié)調(diào)它們以正確的順序運(yùn)行。這個(gè)簡單的策略是革命性的。不在模型中表達(dá)每個(gè)形式變化而是在獨(dú)立的遷移中表達(dá),這個(gè)概念既優(yōu)雅又有效。協(xié)調(diào)數(shù)據(jù)和形式變化是另一個(gè)理念的變化,而且是個(gè)有效的變化。更好的是,這些想法完全不依賴于語言。假設(shè)要構(gòu)建新的Java包裝框架,最好考慮遷移。在這個(gè)系列的下一篇文章中,您將看到新的Ajax和Web效勞支持的框架,它充分利用了Rails中的元編程。屆時(shí)請敞開心靈繼續(xù)跨越邊界。參考資料您可以參閱本文

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論