Ruby on rails 实战圣经: 深度剖析环境设定与Bundler
Complication is WhatHappens When You Try to Solve a Problem You Don’t Understand - Andy Boothe
目錄結(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 的,不過并不強制,定義在任一個 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 錦囊妙計一章介紹 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 測試用途。
因為程序本身是不是寫死是哪一種執(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 項目
rails new my_app將會建立一個叫做 MyApp 的 Rails 項目在./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ù)類別的命名慣例來自動加載。如果你有其他類別檔案需要加載,請在這個設(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 陳述句,請在這里把 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
這個檔案包括了隨機數(shù)生成的一組 key 用來編碼需要保護(hù)的 Cookie 訊息(例如下述的 Cookie session)。修改這組key 會讓已經(jīng)存放在用戶瀏覽器上的 Cookie Session 和 Signed Cookie 失效。你可以用來強制用戶需要重新登入。
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)機是來自本地端的時候,才會將發(fā)生錯誤時的Callstack trace信息給瀏覽器顯示。這個設(shè)定將所有聯(lián)機都當(dāng)做本地端聯(lián)機,好讓開發(fā)模式時所有人聯(lián)機都可以看到錯誤訊息。
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ì)介紹如何實現(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)檔案位置是目前主機的 public 目錄,你可以透過修改 asset_host 變更位置。例如你的靜態(tài)檔案放在不同臺機器或 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 雖然是,但是因為某些內(nèi)部函數(shù)庫不 thread-safe,所以多thread 實際上也是跑在同一顆 CPU。因此,啟用 threaded 模式獲得的性能改善有限,但是設(shè)定上卻麻煩的多,例如你無法使用 Rails 的自動加載類別功能。你也無法在 development 環(huán)境中打開。實務(wù)上我們會在服務(wù)器上執(zhí)行多個 Rails process,因此不需要也不建議打開 threaded 模式。
如果您是使用 JRuby,受益于 Java VM 強大的 Thread 實現(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)機到 http://rubygems.org 下載套件。
bundle package什么時候需要用到這個功能呢? 例如你希望布署的時候避免外部聯(lián)機,或是你有非公開的 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 中有此項設(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 到,但是因為默認(rèn)沒有加到 autoload_paths 之中,所以沒有自動加載的機制。
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ù)的鏈接框架。它實現(xiàn)了一種可以對應(yīng)以 Web 為基礎(chǔ)的Resources 成為本地端支持 CRUD 的對象。
ActiveResource 可以很簡單地實現(xiàn) SOA 架構(gòu)示范,但是作為實際用途上則顯得薄弱。筆者會建議自行實現(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é)
以上是生活随笔為你收集整理的Ruby on rails 实战圣经: 深度剖析环境设定与Bundler的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 句子成分
- 下一篇: 起步HarmonyOS生态的入门学习路线