rails 代码结构详解
目錄結(jié)構(gòu)
這一節(jié)讓我們走訪一個 Rails的目錄結(jié)構(gòu):
app/
app 目錄是你主要工作的地方,不同子目錄存儲了 Models、Controllers、Views、Helpers和 Assets 等檔案。
app/controllers
Controller 的類別檔案存放在這里
app/models
Model 的類別檔案存放在這里
app/views
View 的樣本(template)檔案,依照不同Controllers分子目錄存儲。
app/helpers
Helper 一些在 Views中可以使用的小方法,用來產(chǎn)生較復(fù)雜的 HTML。默認(rèn)的Helper檔案命名是對應(yīng) Controller的,不過并不強(qiáng)制,定義在任一個 Helper檔案中的方法,都可以在任何 Views中使用。
app/assets
Assets 靜態(tài)檔案存放在這里,包括有JavaScript、Stylesheets樣式表單和Images圖檔。詳細(xì)的用法會在Assets一章中介紹。
config/
雖然 Rails的原則是慣例優(yōu)于設(shè)定,不過還是有一些需要設(shè)定的地方。這個目錄下存放了例如數(shù)據(jù)庫配置文件 database.yml、路由設(shè)定routes.rb、應(yīng)用程序配置文件 application.rb 和不同執(zhí)行環(huán)境的配置文件在 config/environments目錄下。
db/
數(shù)據(jù)庫 Schema(綱要)和定義檔 migrations
doc/
你可以將你的文件放在這里
lib/
如果你有一些共享的類別或模塊檔案,可以放在這里,然后用require加載。例如一個放在lib/foobar.rb的類別或模塊檔案,可以在要使用的.rb檔案中這樣加載:
require "foobar"如果放在子目錄lib/foo/bar.rb的話:
require "foo/bar"lib/tasks
Rake 任務(wù)檔案存放在這里,我們會在Rails錦囊妙計(jì)一章介紹 Rake。
log/
不同執(zhí)行環(huán)境的 log檔案會分別記錄在這里
public/
這個目錄對 Web服務(wù)器來說,就是文件根目錄(document root),也就是唯一可以在網(wǎng)絡(luò)上讀取到的目錄。
script/
Rails 的腳本檔案
test/
單元測試、功能測試及整合測試的檔案
tmp/
用來存放暫時用途的檔案
vendor/
第三方函式庫或 Plugin套件會放在這里
其他根目錄下的檔案
多重環(huán)境
Rails 應(yīng)用程序默認(rèn)提供了三種不同的執(zhí)行模式:
不同環(huán)境的差異在于有不同的設(shè)定,除了數(shù)據(jù)庫設(shè)定database.yml里分開設(shè)定之外,個別的環(huán)境設(shè)定放在config/environments/development.rb、config/environments/test.rb和config/environments/production.rb,它們可以有不同的 Log 層級、Session設(shè)定、Email 設(shè)定等等。除了默認(rèn)的這三種模式,我們也可以自定模式,只需要建立對應(yīng)的檔案即可,例如 config/environments/staging.rb。我們會在下一節(jié)詳述這些檔案里面的設(shè)定。
staging 可以用來表示準(zhǔn)上線模式,用來做正式上線前的 QA測試用途。
因?yàn)槌绦虮旧硎遣皇菍懰朗悄囊环N執(zhí)行模式,那么要怎么區(qū)分呢?根據(jù)不同情況有不同方法,包括:
根據(jù)環(huán)境變量 RAILS_ENV或 RACK_ENV 來決定使用哪一種模式,例如使用rake時:
RAILS_ENV=production rake db:migrate下一節(jié)會介紹的rails指令根據(jù)參數(shù)決定:
rails console production rails server -e production最后,應(yīng)用程序服務(wù)器則看服務(wù)器配置文件,例如Passenger里會設(shè)定RackEnv參數(shù),布署一章會詳細(xì)介紹。
Rails 指令
我們已經(jīng)陸續(xù)使用過一些指令了,讓我們看看全部的指令吧:
generate 可縮寫為 g
產(chǎn)生各種不同類型的檔案,例如
rails generate model person rails g controller peopleconsole 可縮寫為 c
開啟一個 Rails控制臺
rails console rails c默認(rèn)的環(huán)境是 developement,如果需要指定環(huán)境,請多輸入環(huán)境名稱即可,例如:
rails c productionRails也有提供沙盒模式(Sandbox),任何數(shù)據(jù)庫的修改都會在離開時回復(fù)(原理是數(shù)據(jù)庫Transaction):
rails c --sandbox在控制臺中輸入exit就會離開。
server 可縮寫為 s
開啟一個 Rails服務(wù)器
rails s默認(rèn)是使用 Port 3000和 development 環(huán)境,如果需要指定:
rails s -p 4000 -e productionnew
建立一個新 Rails項(xiàng)目
rails new my_app將會建立一個叫做 MyApp的 Rails 項(xiàng)目在./my_app 目錄下。加上--database參數(shù)可以改變配置文件的默認(rèn)值,例如:
rails new my_app --database=mysql其他說明可以輸入 rails看到全部的指令。
其他指令
Rails 啟動與應(yīng)用程序設(shè)定
不同的 Rails版本產(chǎn)生的配置文件可能會略有差異,這些配置文件也沒有列出所有Rails設(shè)定,只有列出比較常用的。
啟動整個 Rails程序(包括 rails server, rails runner,rails console等) 時,會執(zhí)行 application.rb的應(yīng)用程序設(shè)定,讓我們來看看這個檔案一些比較重要的部分吧。如果你對這個檔案有修改,無論在什么模式下,都必須重新啟動 Rails設(shè)定才會生效。
# Custom directories with classes and modules you want to be autoloadable. # config.autoload_paths += %W(#{config.root}/extras)任何放在 app/models、app/controllers目錄下的類別檔案,Rails 都會根據(jù)類別的命名慣例來自動加載。如果你有其他類別檔案需要加載,請?jiān)谶@個設(shè)定加入。例如通常我們會加入
config.autoload_paths += %W( #{config.root}/app/lib )如果app/models下的檔案太多,我們可以很簡單地增加新的子目錄來做分類,例如我們可以將檔案直接搬到 app/models/foobar子目錄下(程序內(nèi)容無需修改),然后將這個目錄加進(jìn) autoload_paths即可,例如 config.autoload_paths +=%W( #{config.root}/app/lib #{config.root}/app/models/foobar)。這里的 %W是 Ruby 的數(shù)組簡寫用法。
# Activate observers that should always be running. # config.active_record.observers = :cacher, :garbage_collector, :forum_observer設(shè)定 ActiveRecord的觀察者類別,我們會在 ActiveRecord章節(jié)詳述這個模式,簡單來說,它會在 ActiveRecord數(shù)據(jù)變動時執(zhí)行外部回呼,例如清除快取。
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. # config.time_zone = 'Central Time (US & Canada)'設(shè)定默認(rèn)的應(yīng)用程序時區(qū),默認(rèn)是 UTC。在 Rails中,數(shù)據(jù)庫里面儲存的時間皆為 UTC時間,而設(shè)定此時區(qū)會自動幫你處理轉(zhuǎn)換動作。例如設(shè)定 Taipei的話,從數(shù)據(jù)庫讀取出來時會自動加八小時,存進(jìn)數(shù)據(jù)庫時會自動減八小時。
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] # config.i18n.default_locale = :de設(shè)定默認(rèn)的應(yīng)用程序語系,默認(rèn)是:en。我們會在”I18n多國語系及時區(qū)”一章介紹如何使用。
# Configure sensitive parameters which will be filtered from the log file. config.filter_parameters += [:password]設(shè)定 filter_paramsters可以避免任何叫做 password的參數(shù)值記錄到log 中,有效防止用戶的原始密碼外泄到 log 檔案。
# Use SQL instead of Active Record's schema dumper when creating the database. # This is necessary if your schema can't be completely dumped by the schema dumper, # like if you have constraints or database-specific column types # config.active_record.schema_format = :sql每次跑測試的時候,為了節(jié)省建立數(shù)據(jù)庫的時間,默認(rèn)的schema_format = :ruby會使用 schema.rb 而不是跑 Migrations。不過,schema.rb沒辦法表達(dá)出特定數(shù)據(jù)庫所專屬的功能,像是外部鍵約束(foreignkey constraints)、觸發(fā)(triggers)或是預(yù)存程序(stored procedures)。所以如果你的Migration中有自定的 SQL 陳述句,請?jiān)谶@里把 schema 的格式設(shè)定成:sql。
改用:sql的話,Rails 會倒出現(xiàn)有的 development 數(shù)據(jù)庫,產(chǎn)生#{Rails.env}_structure.sql檔案來作為測試數(shù)據(jù)庫之用。
# Enforce whitelist mode for mass assignment. # This will create an empty whitelist of attributes available for mass-assignment for all models # in your app. As such, your models will need to explicitly whitelist or blacklist accessible # parameters by using an attr_accessible or attr_protected declaration. config.active_record.whitelist_attributes = true ? 預(yù)設(shè)打開*Mass assignment*的白名單設(shè)定,詳見安全性一章。其他初始配置文件(initialzers)
如果將所有的設(shè)定都放到 application.rb就太混亂了,所以非 Rails核心的設(shè)定,我們會放在config/initializers目錄下。這個目錄下的所有.rb檔案會在Rails啟動時都會自動加載執(zhí)行。默認(rèn)產(chǎn)生的檔案有五個:
backtrace silencers
可以讓你選擇性地移除例外追蹤(exceptionbacktrace)訊息,例如有些套件可能會很吵,妨礙你除錯。
inflections
Rails 的命名慣例十分倚賴英文的單復(fù)數(shù),例如將單數(shù)的類別名稱 Person轉(zhuǎn)成復(fù)數(shù)的表格名稱people。Inflector就是負(fù)責(zé)將字符串轉(zhuǎn)換成單復(fù)數(shù)的類別,雖然它內(nèi)建了一些基本的轉(zhuǎn)換規(guī)格,但是英文常常有例外的時候,你可以在這個檔案中加上新的規(guī)格來做修正。如果你不太確定 Rails轉(zhuǎn)換的對不對,請進(jìn)入console控制臺試試看:
$ rails c $ Loading development environment (Rails 3.2.8) $ > "Business".singularize? => "Busines" # 轉(zhuǎn)單數(shù) $ > "moose".pluralize => "mooses"? # 轉(zhuǎn)複數(shù)很不幸地這兩個例子 Rails都沒轉(zhuǎn)對,這時候你就可以利用 inflections.rb來修正。
Rails 核心不接受有關(guān)單復(fù)數(shù)轉(zhuǎn)換的單字錯誤回報,畢竟它不是想做字典。
mime_types
Rails 默認(rèn)支持了如下常見的標(biāo)準(zhǔn) MIME(Multipurpose Internet Mail Extensions)格式,MIME 被用在 HTTP 通訊協(xié)議中的請求標(biāo)頭 Accept和響應(yīng)標(biāo)頭Content-Type中,來說明此文件的格式。例如Accept:application/xml,application/xhtml+xml,text/html;和 Content-Type:text/html; charset=UTF-8。而 Rails會在Controller 的 respond_to 方法中辨識并響應(yīng)所請求的格式樣板,例如瀏覽器請求 application/xml就會響應(yīng)xml 格式
| type/subtype | respond_to symbol | 別名/說明 |
| text/html | :html, :xhtml | application/xhtml+xml |
| text/plain | :text, :txt | ? |
| text/javascript | :js | application/javascript, application/x-javascript |
| text/css | :css | ? |
| text/calendar | :ics | iCalendar 格式 |
| text/csv | :csv | ? |
| application/xml | :xml | text/xml, application/x-xml |
| application/rss+xml | :rss | ? |
| application/atom+xml | :atom | ? |
| application/x-yaml | :yaml | text/yaml |
| application/x-www-form-urlencoded | :url_encoded_form | 默認(rèn)的 HTML forms 格式 |
| multipart/form-data | :multipart_form | HTML forms 格式(包含二進(jìn)制文件數(shù)據(jù)) |
| application/json | :json | text/x-json application/jsonrequest |
如果你需要客制,可以在這里注冊。
secret_token
這個檔案包括了隨機(jī)數(shù)生成的一組 key用來編碼需要保護(hù)的 Cookie訊息(例如下述的 Cookie session)。修改這組key會讓已經(jīng)存放在用戶瀏覽器上的 Cookie Session和 Signed Cookie失效。你可以用來強(qiáng)制用戶需要重新登入。
sesssion_store
Rails 默認(rèn)使用了 Cookie來儲存Session 訊息。它會用上述的 key 編碼之后,直接存放在用戶瀏覽器 Cookie上。除了Cookie Session,我們也可以使用 ActiveRecord儲存在數(shù)據(jù)庫中。我們會在 Controller一章中詳細(xì)介紹及比較。
環(huán)境配置文件
我們在上一節(jié)”多重環(huán)境設(shè)定”曾經(jīng)介紹不同環(huán)境會有不同的配置文件,讓我們來更深入看看有哪些設(shè)定值,以及這些值是如果影響 Development、Production和 Test環(huán)境的不同:
Development 模式
# In the development environment your application's code is reloaded on # every request.? This slows down response time but is perfect for development # since you don't have to restart the webserver when you make code changes. config.cache_classes = false使用 Rails開發(fā)可以快速的原因之一,就是當(dāng)你修改一個小東西,只要重新整理瀏覽器就可以馬上看到修改后的結(jié)果。這個秘訣就在于 cache_classes = false會讓每一次的 HTTP 請求都重載類別檔案。更仔細(xì)的說,當(dāng)這個值是 false的時候,Rails會改用 Ruby的 load 方法,每次執(zhí)行都會重載一次。相反地,如果這個值是 true,則會用 Ruby的 require 方法,只會在第一次碰到的時候加載,之后碰到 require相同的檔案,就會自動忽略,也就是說如果你啟動 Rails后,檔案有修改想看到結(jié)果,必須重新啟動 Rails才行,否則無法立即看到結(jié)果。
# Log error messages when you accidentally call methods on nil. config.whiny_nils = true當(dāng)你對 nil呼叫方法時,會出現(xiàn) NoMethodError。whiny_nils= true會提示你更多訊息來除錯。這個值在 production默認(rèn)是 false。
# Show full error reports and disable caching config.consider_all_requests_local = trueRails只有在聯(lián)機(jī)是來自本地端的時候,才會將發(fā)生錯誤時的Callstack trace信息給瀏覽器顯示。這個設(shè)定將所有聯(lián)機(jī)都當(dāng)做本地端聯(lián)機(jī),好讓開發(fā)模式時所有人聯(lián)機(jī)都可以看到錯誤訊息。
config.action_controller.perform_caching = false是否啟用 Controller層級的快取(我們會在 Controller一章介紹到有哪些快取方法),一般來說在開發(fā)模式不會啟用,除非你要測試它。
# Don't care if the mailer can't send config.action_mailer.raise_delivery_errors = false如果寄信失敗,是否要丟出例外。建議可以改成 true。
建議可以在開發(fā)模式設(shè)定 config.action_mailer.perform_deliveries = false,這樣就不會真的寄信出去。我們會再 ActionMailer一章詳細(xì)介紹如何實(shí)現(xiàn)寄信功能。
# Print deprecation notices to the Rails logger config.active_support.deprecation = :log隨著 Rails版本的升級,如果有方法會在之后的版本中移除,deprecation會提示你如何因應(yīng)。這里的 :log表示會記錄到log 檔案中。
# Only use best-standards-support built into browsers config.action_dispatch.best_standards_support = :builtinRails會在HTTP Header中加上X-UA-Compatible屬性,這個屬性可以用來告訴IE瀏覽器去支持最新網(wǎng)頁標(biāo)準(zhǔn),而不是兼容模式。在這里開發(fā)模式中這里設(shè)成:builtin的意思是IE=edge,而在production模式中默認(rèn)是true,意思是IE=edge,chrome=1,多啟用了Chrome Frame,如果用戶有裝ChromeFrame,就可以讓舊版IE瀏覽器使用Chrome的WebKit引擎來處理網(wǎng)頁,讓舊版IE也可以使用到現(xiàn)代網(wǎng)頁技術(shù)。
http://code.google.com/chrome/chromeframe/
# Log the query plan for queries taking more than this (works # with SQLite, MySQL, and PostgreSQL) config.active_record.auto_explain_threshold_in_seconds = 0.5當(dāng)SQL查詢超過0.5秒時,自動做SQLexplain在Log里。
# Do not compress assets config.assets.compress = false ? # Expands the lines which load the assets config.assets.debug = true以上這兩行Asset Pipeline的設(shè)定會在Asset一章中介紹。
Production 模式
# The production environment is meant for finished, "live" apps. # Code is not reloaded between requests config.cache_classes = truecache_classes = true 表示在 production 中,類別檔案加載進(jìn)內(nèi)存中就快取起來了,大大獲得性能。不像在 development環(huán)境中每一次HTTP 請求就會重載一次。
# Full error reports are disabled and caching is turned on config.consider_all_requests_local?????? = false config.action_controller.perform_caching = true不同于 development,如果在 production環(huán)境出現(xiàn)例外錯誤,不會顯示程序 call stack訊息,而是回傳public/500.html頁面。
# Disable Rails's static asset server (Apache or nginx will already do this) config.serve_static_assets = false不像 development和 test,在這里我們會讓Rails應(yīng)用服務(wù)器關(guān)掉對靜態(tài)檔案的響應(yīng)。在 production環(huán)境中,靜態(tài)檔案應(yīng)該由性能極佳的 Apache或 Nginx 網(wǎng)頁服務(wù)器直接提供檔案。我們會在部署一章詳細(xì)介紹服務(wù)器的架構(gòu)。
# Disable Rails's static asset server (Apache or nginx will already do this) config.serve_static_assets = false ? # Compress JavaScripts and CSS config.assets.compress = true ? # Don't fallback to assets pipeline if a precompiled asset is missed config.assets.compile = false ? # Generate digests for assets URLs config.assets.digest = true ? # Defaults to nil and saved in location specified by config.assets.prefix # config.assets.manifest = YOUR_PATH ? # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) # config.assets.precompile += %w( search.js )這幾個設(shè)定會在Assets一章中介紹。
# Specifies the header that your server uses for sending files # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx“X-Sendfile” 是網(wǎng)頁服務(wù)器提供的功能,可以讓下載文件的動作完全委派給網(wǎng)頁服務(wù)器,Rails送出X-Sendfile 標(biāo)頭后就毋需再占住資源。
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. # config.force_ssl = true是否限制全站必須SSL才能使用。
# See everything in the log (default is :info) # config.log_level = :debug我們在 RESTful應(yīng)用程序一章最后介紹了Logger。這里可以設(shè)定 Logger的層級。默認(rèn) production是:info,其他則是 :debug
# Use a different logger for distributed setups # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)可以更換掉 Rails內(nèi)建的 Logger,例如換成使用syslog的SyslogLogger。
# Use a different cache store in production # config.cache_store = :mem_cache_store設(shè)定不同的快取儲存庫,默認(rèn)是 :memory_store,也就是每個 Rails process各自用內(nèi)存存放。業(yè)界最常用的則是memcached內(nèi)存快取服務(wù)器。
# Enable serving of images, stylesheets, and javascripts from an asset server # config.action_controller.asset_host = "http://assets.example.com"默認(rèn)的靜態(tài)檔案位置是目前主機(jī)的 public目錄,你可以透過修改 asset_host變更位置。例如你的靜態(tài)檔案放在不同臺機(jī)器或 CDN(Content delivery network)上。
這就是為什么 Rails在 View 中會使用 Helper方法的原因之一,我們不會平鋪直敘的寫,而是使用 <%= image_tag(“rails.png”) %>目的就在于透過程序來獲得修改位置的彈性。其他還包括 stylesheets、javascripts等靜態(tài)檔案都有 Helper可以使用。
# Disable delivery errors, bad email addresses will be ignored # config.action_mailer.raise_delivery_errors = false ? # Enable threaded mode # config.threadsafe!雖然 Rails支持 thread-safe 模式,不過這里默認(rèn)是關(guān)閉的。Ruby 1.8的 thread 由于不是操作系統(tǒng)層級的 thread,并不會真的使用到多顆CPU,Ruby 1.9雖然是,但是因?yàn)槟承﹥?nèi)部函數(shù)庫不 thread-safe,所以多thread實(shí)際上也是跑在同一顆 CPU。因此,啟用 threaded模式獲得的性能改善有限,但是設(shè)定上卻麻煩的多,例如你無法使用 Rails的自動加載類別功能。你也無法在 development環(huán)境中打開。實(shí)務(wù)上我們會在服務(wù)器上執(zhí)行多個 Rails process,因此不需要也不建議打開 threaded模式。
如果您是使用 JRuby,受益于 Java VM強(qiáng)大的 Thread 實(shí)現(xiàn),那么就有值得打開 threaded 模式的理由。
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation can not be found) config.i18n.fallbacks = true如果 I18n翻譯檔找不到,則找用默認(rèn)語系的文字。我們會在I18n一章詳細(xì)介紹多國語系功能。
# Send deprecation notices to registered listeners config.active_support.deprecation = :notify將 deprecation訊息傳到Notifications頻道,你可以用以下程序去訂閱這個訊息:
ActiveSupport::Notifications.subscribe("deprecation.rails") do |message, callstack| ? # deprecation message end如果沒有訂閱的話,就什么事都不會發(fā)生。
Test 模式
# Show full error reports and disable caching config.consider_all_requests_local?????? = true config.action_controller.perform_caching = false ? # Raise exceptions instead of rendering exception templates config.action_dispatch.show_exceptions = false不同于 development或 production 碰到例外會捕捉例外后,給瀏覽器顯示出 call stack trace或public/500.html畫面,在 test 模式就不處理,讓例外直接爆出。
# Tell Action Mailer not to deliver emails to the real world. # The :test delivery method accumulates sent emails in the # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test測試模式下不會真的去寄送email
# Print deprecation notices to the stderr config.active_support.deprecation = :stderr讓 deprecation訊息會直接顯示到窗口之中。
數(shù)據(jù)庫配置文件 database.yml
幾乎每一個 Rails應(yīng)用程序都會與數(shù)據(jù)庫互動。而數(shù)據(jù)庫需要一個配置文件是 config/database.yml。如果你打開這個檔案,你會發(fā)現(xiàn)默認(rèn)設(shè)定是 SQLite3。這個檔案包含三個不同的部分,對應(yīng)到三個 Rails 默認(rèn)環(huán)境。
一個 MySQL的配置文件范例如下:
development: ? adapter: mysql ? encoding: utf8 ? database: blog_development ? username: root ? password: production: ? adapter: mysql ? encoding: utf8 ? database: blog_production ? username: root ? password: test: ? adapter: mysql ? encoding: utf8 ? database: blog_test ? username: root ? password:Bundler 與 Gemfile 配置文件
Bundler http://gembundler.com/是管理應(yīng)用程序 Gem 相關(guān)性(dependencies)管理工具,它會根據(jù) Gemfile的設(shè)定自動下載及安裝Gem 套件,并且?guī)湍憬鉀Q不同套件之間的依存關(guān)系,更重要的是,它可以讓不同開發(fā)者之間和布署時,所有依存套件的版本都能夠一致。
在 Rails3中 (Bundler 不只用在Rails3,其他例如 Sinatra或是 Rails2 也都可以使用) 要使用的 Gems,都必須宣告在Gemfile配置文件中,沒寫在里面的話,就算手動 require也找不到。這跟 Rails2 以前可以直接require 任意 rubygems不同,在使用 Bundler 的環(huán)境中,要require 什么 rubygems必須透過 Gemfile 管理。
Gemfile 的寫法說明如下:
? # 第二個參數(shù)可以指定版本 ? gem "rails", "3.2.8" ? ? # 也可以不指定版本,這樣會安裝最新的穩(wěn)定版本 (不包括 .pre 或 .rc 結(jié)尾的版本) ? gem 'mysql2' ? ??# 如果 require 的檔名不同,可以加上 :require ? gem 'yajl-ruby', :require => 'yajl' ? ? # 可以用 Git 當(dāng)做來源(根目錄要有 .gemspec 檔案),甚至可以指定 branch, tag 或 ref。 ? gem 'authlogic', :git => 'git://github.com/odorcicd/authlogic.git', ??????????????????????????? :branch => 'rails3' ? ? # 也可以直接用電腦裡的其他目錄 ? # gem "rails", :path => '/Users/ihower/github/rails' ? ? # Group 功能可以讓特定環(huán)境才會載入 ? group :development, :test do ???? gem "rspec", "~> 2.0" ???? gem "rspec-rails", "~> 2.0" ? end版號的指定方式除了指定特定版本,還可以指定大于等于 >=某個版本。不過最建議的方式則是使用 ~>的語法。”~> x.y.z” 的意思是版號 x,y 固定,但可以大于等于 z。例如 “~> 1.3.5”的意思是 1.3.5, 1.3.6, 1.3.9可以安裝,但是 1.4.0, 1.5.5, 2.0.1就不行。這種寫法的好處是,通常版號的命名有其慣例:x major版號升級表示有 API 發(fā)生不向后的兼容性變動,y minor 版號升級表示有功能新增,z tiny 版號升級表示 bugs 修正。因此 “~> x.y.z”可以讓我們保有升級彈性,又不致于升級太多讓程序發(fā)生不兼容錯誤。
安裝及更新 Gems
如果你修改了這個檔案,請執(zhí)行 bundle install,這樣 Bundler就會檢查并安裝這些函式庫,并產(chǎn)生一個 Gemfile.lock檔案。Gemfile.lock檔案會詳細(xì)列出所有使用到的套件版本,你應(yīng)該把這個檔案也commit送進(jìn)版本控制系統(tǒng),這樣其他開發(fā)者及上線的版本就都會安裝完全一樣的版本了。
執(zhí)行 bundle update gem_name則會更新此 gem 的版本。bundleupdate 則會檢查所有的 gem 更新到最新版本。一般來說你只需要在每次 Gemfile修改后,執(zhí)行bundle install即可。如果有套件關(guān)連性 bundle install無法解決,它會提示你執(zhí)行 bundle update。
什么時候該執(zhí)行 bundle install或 bundle update呢? 一般來說,總是執(zhí)行 bundle install即可。這個指令只會做必要的更新到 Gemfile.lock,執(zhí)行速度較快,它不會幫你升級現(xiàn)有的 Gem。而 bundleupdate會重新產(chǎn)生整個 Gemfile.lock檔案,更新所有 Gem 到最新版本。但是,一次升級太多套件,可能會造成除錯上的困難。因此會建議如果要升級,請執(zhí)行 bundle update gem_name一次升級一個套件。
怎么知道可以升級哪些Gem呢?
bundle outdated???這個指令就會列出有新版本可以升級的gems。
打包 Gems
執(zhí)行以下指令,會將所有用到的 Gems打包進(jìn) vendor/cache目錄。如此執(zhí)行bundle install時就不會聯(lián)機(jī)到 http://rubygems.org下載套件。
bundle package什么時候需要用到這個功能呢?例如你希望布署的時候避免外部聯(lián)機(jī),或是你有非公開的 gems不會上傳到http://rubygems.org網(wǎng)站上。
如果你有非 Rails的 script 需要執(zhí)行(也就是放在 Gemfile檔案中的 Gem 所自行提供的執(zhí)行檔),使用 bundle exec可以正確的加載 Bundler的環(huán)境。例如 bundle exec rspec spec/
名稱慣例
在 Rails中有一些命名上的慣例:
類別命名與自動加載
檔名使用小寫、單數(shù),用底線區(qū)隔。例如當(dāng) Rails看到一個 OrderItem 的類別或模塊(Module),它會在 autoload_paths (我們在config/application.rb中有此項(xiàng)設(shè)定) 目錄中自動去加載叫做 order_item.rb的檔案,也就是require “order_item”。
如果是有嵌套的類別或模塊,例如Admin::OrderItem,則會多一層目錄,它會自動加載admin/order_item.rb的檔案,也就是 require“admin/order_item”。
如果你沒有設(shè)定 autoload_paths加入 lib 目錄,或是你的檔案沒有依照慣例命名,那么你會需要在程序中手動 require它?;旧?#xff0c;只要依照命名慣例,你不太需要在程序中寫 require。
autoload_paths 目錄是指 Rails 會自動根據(jù)命名慣例加載,而 Ruby的$LOAD_PATH 常數(shù)則是 require 時會尋找的目錄。像 lib這個目錄 Rails 默認(rèn)就只有加到 $LOAD_PATH 之中,所以你放在 lib 的檔案是可以 require到,但是因?yàn)槟J(rèn)沒有加到 autoload_paths之中,所以沒有自動加載的機(jī)制。
Model 命名
類別名稱使用大寫、單數(shù),沒有底線。而檔名使用小寫、單數(shù),用底線。數(shù)據(jù)庫表格名稱用小寫且為復(fù)數(shù)。例如:
Controller 命名
假設(shè)有一個store controller的話:
如果需要將controllers檔案做分類,這時候可以使用Mobules,將檔案放在子目錄下,例如后臺專用的controllers:
View 命名
例如一個叫做 People的 controller,其中的index action:
Rails 組件導(dǎo)覽
Rails 包含許多個別的函式庫組件:
Action Pack
Action Pack 是個包含 Action Controller、ActionView和 Action Dispatch的 gem。也就是“MVC”中的 “VC” 部分。
Action Controller
Action Controller 是 Rails應(yīng)用程序中,管理Controllers的組件。Action Controller框架處理傳給 Rails 的 HTTP 請求,萃取出參數(shù),然后分派給所屬的 Action。ActionController還提供了 session 管理、樣板演算顯示(template rendering)和 redirect 功能。
Action View
Action View 負(fù)責(zé) Rails應(yīng)用程序中的Views。它默認(rèn)可以產(chǎn)生 HTML或 XML 輸出。ActionView負(fù)責(zé)樣板的演算顯示(template rendering),包括嵌套(nesting)或局部(partial)樣板,甚至也內(nèi)建支持一些 Ajax。
Action Dispatch
Action Dispatch 處理 HTTP請求的路由(routing),它把 HTTP請求發(fā)派(dispatch)到它該去的地方,也許是你的應(yīng)用程序或其他 Rack程序。
Action Mailer
Action Mailer 是個建構(gòu) E-mail功能的框架。你可以使用Action Mailer來接收來信,或是使用樣板來寄出純文本或復(fù)雜的multipart信件。
Active Model
Active Model 在 Action Pack gem和 ORMgem (例如 Active Record)之間定義了一組接口。Active Model允許Rails 可以依你的需求把 Active Record換成其他 ORM 框架。
Active Record
Active Record 是 Rails應(yīng)用程序中的Models 基礎(chǔ)。它不依存特定的數(shù)據(jù)庫系統(tǒng),提供了 CRUD功能、先進(jìn)的查詢能力以及可以跟其他 Models關(guān)聯(lián)的本事。
Active Resource
Active Resource 提供了與其他業(yè)務(wù)對象和 RESTful網(wǎng)絡(luò)服務(wù)的鏈接框架。它實(shí)現(xiàn)了一種可以對應(yīng)以 Web為基礎(chǔ)的Resources 成為本地端支持 CRUD 的對象。
ActiveResource 可以很簡單地實(shí)現(xiàn) SOA 架構(gòu)示范,但是作為實(shí)際用途上則顯得薄弱。筆者會建議自行實(shí)現(xiàn)客戶端程序,請參考Service-Oriented Design and Implement with Rails3 投影片。Rails4也將移除這個組件。
Active Support
Active Support 是 Rails里的工具函式庫,它也擴(kuò)充了一些 Ruby標(biāo)準(zhǔn)函式庫。除了被用在Rails核心程序中,你也可以在你的程序中使用。
Railties
Railties 是 Rails的核心程序代碼,用來把以上各種的框架函式庫以及 Plugin全部組合在一起。
總結(jié)
以上是生活随笔為你收集整理的rails 代码结构详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 涨握在线|马云接班人;外资取限;iPho
- 下一篇: 使用Flexible实现手淘H5页面的终