# 設置 Rails 程序
本文介紹 Rails 程序的設置和初始化。
讀完本文,你將學到:
* 如何調整 Rails 程序的表現;
* 如何在程序啟動時運行其他代碼;
### Chapters
1. [初始化代碼的存放位置](#%E5%88%9D%E5%A7%8B%E5%8C%96%E4%BB%A3%E7%A0%81%E7%9A%84%E5%AD%98%E6%94%BE%E4%BD%8D%E7%BD%AE)
2. [加載 Rails 前運行代碼](#%E5%8A%A0%E8%BD%BD-rails-%E5%89%8D%E8%BF%90%E8%A1%8C%E4%BB%A3%E7%A0%81)
3. [設置 Rails 組件](#%E8%AE%BE%E7%BD%AE-rails-%E7%BB%84%E4%BB%B6)
* [3常規選項](#3%E5%B8%B8%E8%A7%84%E9%80%89%E9%A1%B9)
* [3設置靜態資源](#3%E8%AE%BE%E7%BD%AE%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90)
* [3設置生成器](#3%E8%AE%BE%E7%BD%AE%E7%94%9F%E6%88%90%E5%99%A8)
* [3設置中間件](#3%E8%AE%BE%E7%BD%AE%E4%B8%AD%E9%97%B4%E4%BB%B6)
* [3設置 i18n](#3%E8%AE%BE%E7%BD%AE-i18n)
* [3設置 Active Record](#3%E8%AE%BE%E7%BD%AE-active-record)
* [3設置 Action Controller](#3%E8%AE%BE%E7%BD%AE-action-controller)
* [3設置 Action Dispatch](#3%E8%AE%BE%E7%BD%AE-action-dispatch)
* [3設置 Action View](#3%E8%AE%BE%E7%BD%AE-action-view)
* [3設置 Action Mailer](#3%E8%AE%BE%E7%BD%AE-action-mailer)
* [3設置 Active Support](#3%E8%AE%BE%E7%BD%AE-active-support)
* [3設置數據庫](#3%E8%AE%BE%E7%BD%AE%E6%95%B0%E6%8D%AE%E5%BA%93)
* [3連接設置](#3%E8%BF%9E%E6%8E%A5%E8%AE%BE%E7%BD%AE)
* [3新建 Rails 環境](#3%E6%96%B0%E5%BB%BA-rails-%E7%8E%AF%E5%A2%83)
* [3部署到子目錄中](#3%E9%83%A8%E7%BD%B2%E5%88%B0%E5%AD%90%E7%9B%AE%E5%BD%95%E4%B8%AD)
4. [Rails 環境設置](#rails-%E7%8E%AF%E5%A2%83%E8%AE%BE%E7%BD%AE)
5. [使用初始化腳本](#%E4%BD%BF%E7%94%A8%E5%88%9D%E5%A7%8B%E5%8C%96%E8%84%9A%E6%9C%AC)
6. [初始化事件](#%E5%88%9D%E5%A7%8B%E5%8C%96%E4%BA%8B%E4%BB%B6)
* [3`Rails::Railtie#initializer`](#3rails::railtie#initializer)
* [3初始化腳本](#3%E5%88%9D%E5%A7%8B%E5%8C%96%E8%84%9A%E6%9C%AC)
7. [數據庫連接池](#%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E6%B1%A0)
### 1 初始化代碼的存放位置
Rails 的初始化代碼存放在四個標準位置:
* `config/application.rb` 文件
* 針對特定環境的設置文件;
* 初始化腳本;
* 后置初始化腳本;
### 2 加載 Rails 前運行代碼
如果想在加載 Rails 之前運行代碼,可以把代碼添加到 `config/application.rb` 文件的 `require 'rails/all'` 之前。
### 3 設置 Rails 組件
總的來說,設置 Rails 的工作包括設置 Rails 的組件以及 Rails 本身。在設置文件 `config/application.rb` 和針對特定環境的設置文件(例如 `config/environments/production.rb`)中可以指定傳給各個組件的不同設置項目。
例如,在文件 `config/application.rb` 中有下面這個設置:
```
config.autoload_paths += %W(#{config.root}/extras)
```
這是針對 Rails 本身的設置項目。如果想設置單獨的 Rails 組件,一樣可以在 `config/application.rb` 文件中使用同一個 `config` 對象:
```
config.active_record.schema_format = :ruby
```
Rails 會使用指定的設置配置 Active Record。
#### 3.1 3常規選項
下面這些設置方法在 `Rails::Railtie` 對象上調用,例如 `Rails::Engine` 或 `Rails::Application` 的子類。
* `config.after_initialize`:接受一個代碼塊,在 Rails 初始化程序之后執行。初始化的過程包括框架本身,引擎,以及 `config/initializers` 文件夾中所有的初始化腳本。注意,Rake 任務也會執行代碼塊中的代碼。常用于設置初始化腳本用到的值。
```
config.after_initialize do
ActionView::Base.sanitized_allowed_tags.delete 'div'
end
```
* `config.asset_host`:設置靜態資源的主機。可用于設置靜態資源所用的 CDN,或者通過不同的域名繞過瀏覽器對并發請求數量的限制。是 `config.action_controller.asset_host` 的簡化。
* `config.autoload_once_paths`:一個由路徑組成的數組,Rails 從這些路徑中自動加載常量,且在多次請求之間一直可用。只有 `config.cache_classes` 為 `false`(開發環境中的默認值)時才有效。如果為 `true`,所有自動加載的代碼每次請求時都會重新加載。這個數組中的路徑必須出現在 `autoload_paths` 設置中。默認為空數組。
* `config.autoload_paths`:一個由路徑組成的數組,Rails 從這些路徑中自動加載常量。默認值為 `app` 文件夾中的所有子文件夾。
* `config.cache_classes`:決定程序中的類和模塊在每次請求中是否要重新加載。在開發環境中的默認值是 `false`,在測試環境和生產環境中的默認值是 `true`。調用 `threadsafe!` 方法的作用和設為 `true` 一樣。
* `config.action_view.cache_template_loading`:決定模板是否要在每次請求時重新加載。默認值等于 `config.cache_classes` 的值。
* `config.beginning_of_week`:設置一周從哪天開始。可使用的值是一周七天名稱的符號形式,例如 `:monday`。
* `config.cache_store`:設置 Rails 緩存的存儲方式。可選值有:`:memory_store`,`:file_store`,`:mem_cache_store`,`:null_store`,以及實現了緩存 API 的對象。如果文件夾 `tmp/cache` 存在,默認值為 `:file_store`,否則為 `:memory_store`。
* `config.colorize_logging`:設定日志信息是否使用 ANSI 顏色代碼。默認值為 `true`。
* `config.consider_all_requests_local`:如果設為 `true`,在 HTTP 響應中會顯示詳細的調試信息,而且 `Rails::Info` 控制器會在地址 `/rails/info/properties` 上顯示程序的運行時上下文。在開發環境和測試環境中默認值為 `true`,在生產環境中默認值為 `false`。要想更精確的控制,可以把這個選項設為 `false`,然后在控制器中實現 `local_request?` 方法,指定哪些請求要顯示調試信息。
* `config.console`:設置執行 `rails console` 命令時使用哪個類實現控制臺,最好在 `console` 代碼塊中設置:
```
console do
# this block is called only when running console,
# so we can safely require pry here
require "pry"
config.console = Pry
end
```
* `config.dependency_loading`:設為 `false` 時禁止自動加載常量。只有 `config.cache_classes` 為 `true`(生產環境的默認值)時才有效。`config.threadsafe!` 為 `true` 時,這個選項為 `false`。
* `config.eager_load`:設為 `true` 是按需加載 `config.eager_load_namespaces` 中的所有命名空間,包括程序本身、引擎、Rails 框架和其他注冊的命名空間。
* `config.eager_load_namespaces`:注冊命名空間,`config.eager_load` 為 `true` 時按需加載。所有命名空間都要能響應 `eager_load!` 方法。
* `config.eager_load_paths`:一個由路徑組成的數組,`config.cache_classes` 為 `true` 時,Rails 啟動時按需加載對應的代碼。
* `config.encoding`:設置程序全局編碼,默認為 UTF-8。
* `config.exceptions_app`:設置拋出異常后中間件 ShowException 調用哪個異常處理程序。默認為 `ActionDispatch::PublicExceptions.new(Rails.public_path)`。
* `config.file_watcher`:設置監視文件系統上文件變化使用的類,`config.reload_classes_only_on_change` 為 `true` 時才有效。指定的類必須符合 `ActiveSupport::FileUpdateChecker` API。
* `config.filter_parameters`:過濾不想寫入日志的參數,例如密碼,信用卡卡號。把 `config.filter_parameters+=[:password]` 加入文件 `config/initializers/filter_parameter_logging.rb`,可以過濾密碼。
* `config.force_ssl`:強制所有請求使用 HTTPS 協議,通過 `ActionDispatch::SSL` 中間件實現。
* `config.log_formatter`:設置 Rails 日志的格式化工具。在生產環境中默認值為 `Logger::Formatter`,其他環境默認值為 `ActiveSupport::Logger::SimpleFormatter`。
* `config.log_level`:設置 Rails 日志等級。在生產環境中默認值為 `:info`,其他環境默認值為 `:debug`。
* `config.log_tags`:一組可響應 `request` 對象的方法。可在日志消息中加入更多信息,例如二級域名和請求 ID,便于調試多用戶程序。
* `config.logger`:接受一個實現了 Log4r 接口的類,或者使用默認的 `Logger` 類。默認值為 `ActiveSupport::Logger`,在生產環境中關閉了自動沖刷功能。
* `config.middleware`:設置程序使用的中間件。詳情參閱“[設置中間件](#configuring-middleware)”一節。
* `config.reload_classes_only_on_change`:只當監視的文件變化時才重新加載。默認值為 `true`,監視 `autoload_paths` 中所有路徑。如果 `config.cache_classes` 為 `true`,忽略這個設置。
* `secrets.secret_key_base`: 指定一個密令,和已知的安全密令比對,防止篡改會話。新建程序時會生成一個隨機密令,保存在文件 `config/secrets.yml` 中。
* `config.serve_static_assets`:讓 Rails 伺服靜態資源文件。默認值為 `true`,但在生產環境中為 `false`,因為應該使用服務器軟件(例如 Nginx 或 Apache)伺服靜態資源文件。 如果測試程序,或者在生產環境中使用 WEBrick(極力不推薦),應該設為 `true`,否則無法使用頁面緩存,請求 `public` 文件夾中的文件時也會經由 Rails 處理。
* `config.session_store`:一般在 `config/initializers/session_store.rb` 文件中設置,指定使用什么方式存儲會話。可用值有:`:cookie_store`(默認),`:mem_cache_store` 和 `:disabled`。`:disabled` 指明不讓 Rails 處理會話。當然也可指定自定義的會話存儲:
```
config.session_store :my_custom_store
```
這個自定義的存儲方式必須定義為 `ActionDispatch::Session::MyCustomStore`。
* `config.time_zone`:設置程序使用的默認時區,也讓 Active Record 使用這個時區。
#### 3.2 3設置靜態資源
* `config.assets.enabled`:設置是否啟用 Asset Pipeline。默認啟用。
* `config.assets.raise_runtime_errors`:設為 `true`,啟用額外的運行時錯誤檢查。建議在 `config/environments/development.rb` 中設置,這樣可以盡量減少部署到生產環境后的異常表現。
* `config.assets.compress`:是否壓縮編譯后的靜態資源文件。在 `config/environments/production.rb` 中為 `true`。
* `config.assets.css_compressor`:設定使用的 CSS 壓縮程序,默認為 `sass-rails`。目前,唯一可用的另一個值是 `:yui`,使用 `yui-compressor` gem 壓縮文件。
* `config.assets.js_compressor`:設定使用的 JavaScript 壓縮程序。可用值有:`:closure`,`:uglifier` 和 `:yui`。分別需要安裝 `closure-compiler`,`uglifier` 和 `yui-compressor` 這三個 gem。
* `config.assets.paths`:查找靜態資源文件的路徑。Rails 會在這個選項添加的路徑中查找靜態資源文件。
* `config.assets.precompile`:指定執行 `rake assets:precompile` 任務時除 `application.css` 和 `application.js` 之外要編譯的其他資源文件。
* `config.assets.prefix`:指定伺服靜態資源文件時使用的地址前綴,默認為 `/assets`。
* `config.assets.digest`:在靜態資源文件名中加入 MD5 指紋。在 `production.rb` 中默認設為 `true`。
* `config.assets.debug`:禁止合并和壓縮靜態資源文件。在 `development.rb` 中默認設為 `true`。
* `config.assets.cache_store`:設置 Sprockets 使用的緩存方式,默認使用文件存儲。
* `config.assets.version`:生成 MD5 哈希時用到的一個字符串。可用來強制重新編譯所有文件。
* `config.assets.compile`:布爾值,用于在生產環境中啟用 Sprockets 實時編譯功能。
* `config.assets.logger`:接受一個實現了 Log4r 接口的類,或者使用默認的 `Logger` 類。默認值等于 `config.logger` 選項的值。把 `config.assets.logger` 設為 `false`,可以關閉靜態資源相關的日志。
#### 3.3 3設置生成器
Rails 允許使用 `config.generators` 方法設置使用的生成器。這個方法接受一個代碼塊:
```
config.generators do |g|
g.orm :active_record
g.test_framework :test_unit
end
```
在代碼塊中可用的方法如下所示:
* `assets`:是否允許腳手架創建靜態資源文件,默認為 `true`。
* `force_plural`:是否允許使用復數形式的模型名,默認為 `false`。
* `helper`:是否生成幫助方法文件,默認為 `true`。
* `integration_tool`:設置使用哪個集成工具,默認為 `nil`。
* `javascripts`:是否允許腳手架創建 JavaScript 文件,默認為 `true`。
* `javascript_engine`:設置生成靜態資源文件時使用的預處理引擎(例如 CoffeeScript),默認為 `nil`。
* `orm`:設置使用哪個 ORM。默認為 `false`,使用 Active Record。
* `resource_controller`:設定執行 `rails generate resource` 命令時使用哪個生成器生成控制器,默認為 `:controller`。
* `scaffold_controller`:和 `resource_controller` 不同,設定執行 `rails generate scaffold` 命令時使用哪個生成器生成控制器,默認為 `:scaffold_controller`。
* `stylesheets`:是否啟用生成器中的樣式表文件鉤子,在執行腳手架時使用,也可用于其他生成器,默認值為 `true`。
* `stylesheet_engine`:設置生成靜態資源文件時使用的預處理引擎(例如 Sass),默認為 `:css`。
* `test_framework`:設置使用哪個測試框架,默認為 `false`,使用 Test::Unit。
* `template_engine`:設置使用哪個模板引擎,例如 ERB 或 Haml,默認為 `:erb`。
#### 3.4 3設置中間件
每個 Rails 程序都使用了一組標準的中間件,在開發環境中的加載順序如下:
* `ActionDispatch::SSL`:強制使用 HTTPS 協議處理每個請求。`config.force_ssl` 設為 `true` 時才可用。`config.ssl_options` 選項的值會傳給這個中間件。
* `ActionDispatch::Static`:用來伺服靜態資源文件。如果 `config.serve_static_assets` 設為 `false`,則不會使用這個中間件。
* `Rack::Lock`:把程序放入互斥鎖中,一次只能在一個線程中運行。`config.cache_classes` 設為 `false` 時才會使用這個中間件。
* `ActiveSupport::Cache::Strategy::LocalCache`:使用內存存儲緩存。這種存儲方式對線程不安全,而且只能在單個線程中做臨時存儲。
* `Rack::Runtime`:設定 `X-Runtime` 報頭,其值為處理請求花費的時間,單位為秒。
* `Rails::Rack::Logger`:開始處理請求時寫入日志,請求處理完成后沖刷所有日志。
* `ActionDispatch::ShowExceptions`:捕獲程序拋出的異常,如果在本地處理請求,或者 `config.consider_all_requests_local` 設為 `true`,會渲染一個精美的異常頁面。如果 `config.action_dispatch.show_exceptions` 設為 `false`,則會直接拋出異常。
* `ActionDispatch::RequestId`:在響應中加入一個唯一的 `X-Request-Id` 報頭,并啟用 `ActionDispatch::Request#uuid` 方法。
* `ActionDispatch::RemoteIp`:從請求報頭中獲取正確的 `client_ip`,檢測 IP 地址欺騙攻擊。通過 `config.action_dispatch.ip_spoofing_check` 和 `config.action_dispatch.trusted_proxies` 設置。
* `Rack::Sendfile`:響應主體為一個文件,并設置 `X-Sendfile` 報頭。通過 `config.action_dispatch.x_sendfile_header` 設置。
* `ActionDispatch::Callbacks`:處理請求之前運行指定的回調。
* `ActiveRecord::ConnectionAdapters::ConnectionManagement`:每次請求后都清理可用的連接,除非把在請求環境變量中把 `rack.test` 鍵設為 `true`。
* `ActiveRecord::QueryCache`:緩存請求中使用的 `SELECT` 查詢。如果用到了 `INSERT` 或 `UPDATE` 語句,則清除緩存。
* `ActionDispatch::Cookies`:設置請求的 cookie。
* `ActionDispatch::Session::CookieStore`:把會話存儲在 cookie 中。`config.action_controller.session_store` 設為其他值時則使用其他中間件。`config.action_controller.session_options` 的值會傳給這個中間件。
* `ActionDispatch::Flash`:設定 `flash` 鍵。必須為 `config.action_controller.session_store` 設置一個值,才能使用這個中間件。
* `ActionDispatch::ParamsParser`:解析請求中的參數,生成 `params`。
* `Rack::MethodOverride`:如果設置了 `params[:_method]`,則使用相應的方法作為此次請求的方法。這個中間件提供了對 PATCH、PUT 和 DELETE 三個 HTTP 請求方法的支持。
* `ActionDispatch::Head`:把 HEAD 請求轉換成 GET 請求,并處理請求。
除了上述標準中間件之外,還可使用 `config.middleware.use` 方法添加其他中間件:
```
config.middleware.use Magical::Unicorns
```
上述代碼會把中間件 `Magical::Unicorns` 放入中間件列表的最后。如果想在某個中間件之前插入中間件,可以使用 `insert_before`:
```
config.middleware.insert_before ActionDispatch::Head, Magical::Unicorns
```
如果想在某個中間件之后插入中間件,可以使用 `insert_after`:
```
config.middleware.insert_after ActionDispatch::Head, Magical::Unicorns
```
中間件還可替換成其他中間件:
```
config.middleware.swap ActionController::Failsafe, Lifo::Failsafe
```
也可從中間件列表中刪除:
```
config.middleware.delete "Rack::MethodOverride"
```
#### 3.5 3設置 i18n
下述設置項目都針對 `I18n` 代碼庫。
* `config.i18n.available_locales`:設置程序可用本地語言的白名單。默認值為可在本地化文件中找到的所有本地語言,在新建程序中一般是 `:en`。
* `config.i18n.default_locale`:設置程序的默認本地化語言,默認值為 `:en`。
* `config.i18n.enforce_available_locales`:確保傳給 i18n 的本地語言在 `available_locales` 列表中,否則拋出 `I18n::InvalidLocale` 異常。默認值為 `true`。除非特別需要,不建議禁用這個選項,因為這是一項安全措施,能防止用戶提供不可用的本地語言。
* `config.i18n.load_path`:設置 Rails 搜尋本地化文件的路徑。默認為 config/locales/*.{yml,rb}`。
#### 3.6 3設置 Active Record
`config.active_record` 包含很多設置項:
* `config.active_record.logger`:接受一個實現了 Log4r 接口的類,或者使用默認的 `Logger` 類,然后傳給新建的數據庫連接。在 Active Record 模型類或模型實例上調用 `logger` 方法可以獲取這個日志類。設為 `nil` 禁用日志。
* `config.active_record.primary_key_prefix_type`:調整主鍵的命名方式。默認情況下,Rails 把主鍵命名為 `id`(無需設置這個選項)。除此之外還有另外兩個選擇:
* `:table_name`:`Customer` 模型的主鍵為 `customerid`;
* `:table_name_with_underscore`: `Customer` 模型的主鍵為 `customer_id`;
* `config.active_record.table_name_prefix`:設置一個全局字符串,作為數據表名的前綴。如果設為 `northwest_`,那么 `Customer` 模型對應的表名為 `northwest_customers`。默認為空字符串。
* `config.active_record.table_name_suffix`:設置一個全局字符串,作為數據表名的后綴。如果設為 `_northwest`,那么 `Customer` 模型對應的表名為 `customers_northwest`。默認為空字符串。
* `config.active_record.schema_migrations_table_name`:設置模式遷移數據表的表名。
* `config.active_record.pluralize_table_names`:設置 Rails 在數據庫中要尋找單數形式還是復數形式的數據表。如果設為 `true`(默認值),`Customer` 類對應的數據表是 `customers`。如果設為 `false`,`Customer` 類對應的數據表是 `customer`。
* `config.active_record.default_timezone`:從數據庫中查詢日期和時間時使用 `Time.local`(設為 `:local` 時)還是 `Time.utc`(設為 `:utc` 時)。默認為 `:utc`。
* `config.active_record.schema_format`:設置導出數據庫模式到文件時使用的格式。可選項包括:`:ruby`,默認值,根據遷移導出模式,與數據庫種類無關;`:sql`,導出為 SQL 語句,受數據庫種類影響。
* `config.active_record.timestamped_migrations`:設置遷移編號使用連續的數字還是時間戳。默認值為 `true`,使用時間戳。如果有多名開發者協作,建議使用時間戳。
* `config.active_record.lock_optimistically`:設置 Active Record 是否使用樂觀鎖定,默認使用。
* `config.active_record.cache_timestamp_format`:設置緩存鍵中使用的時間戳格式,默認為 `:number`。
* `config.active_record.record_timestamps`:設置是否記錄 `create` 和 `update` 動作的時間戳。默認為 `true`。
* `config.active_record.partial_writes`: 布爾值,設置是否局部寫入(例如,只更新有變化的屬性)。注意,如果使用局部寫入,還要使用樂觀鎖定,因為并發更新寫入的數據可能已經過期。默認值為 `true`。
* `config.active_record.attribute_types_cached_by_default`:設置讀取時 `ActiveRecord::AttributeMethods` 緩存的字段類型。默認值為 `[:datetime, :timestamp, :time, :date]`。
* `config.active_record.maintain_test_schema`:設置運行測試時 Active Record 是否要保持測試數據庫的模式和 `db/schema.rb` 文件(或 `db/structure.sql`)一致,默認為 `true`。
* `config.active_record.dump_schema_after_migration`:設置運行遷移后是否要導出數據庫模式到文件 `db/schema.rb` 或 `db/structure.sql` 中。這項設置在 Rails 生成的 `config/environments/production.rb` 文件中為 `false`。如果不設置這個選項,則值為 `true`。
MySQL 適配器添加了一項額外設置:
* `ActiveRecord::ConnectionAdapters::MysqlAdapter.emulate_booleans`:設置 Active Record 是否要把 MySQL 數據庫中 `tinyint(1)` 類型的字段視為布爾值,默認為 `true`。
模式導出程序添加了一項額外設置:
* `ActiveRecord::SchemaDumper.ignore_tables`:指定一個由數據表組成的數組,導出模式時不會出現在模式文件中。僅當 `config.active_record.schema_format == :ruby` 時才有效。
#### 3.7 3設置 Action Controller
`config.action_controller` 包含以下設置項:
* `config.action_controller.asset_host`:設置靜態資源的主機,不用程序的服務器伺服靜態資源,而使用 CDN。
* `config.action_controller.perform_caching`:設置程序是否要緩存。在開發模式中為 `false`,生產環境中為 `true`。
* `config.action_controller.default_static_extension`:設置緩存文件的擴展名,默認為 `.html`。
* `config.action_controller.default_charset`:設置默認字符集,默認為 `utf-8`。
* `config.action_controller.logger`:接受一個實現了 Log4r 接口的類,或者使用默認的 `Logger` 類,用于寫 Action Controller 中的日志消息。設為 `nil` 禁用日志。
* `config.action_controller.request_forgery_protection_token`:設置請求偽造保護的權標參數名。默認情況下調用 `protect_from_forgery` 方法,將其設為 `:authenticity_token`。
* `config.action_controller.allow_forgery_protection`:是否啟用跨站請求偽造保護功能。在測試環境中默認為 `false`,其他環境中默認為 `true`。
* `config.action_controller.relative_url_root`:用來告知 Rails 程序[部署在子目錄中](#deploy-to-a-subdirectory-relative-url-root)。默認值為 `ENV['RAILS_RELATIVE_URL_ROOT']`。
* `config.action_controller.permit_all_parameters`:設置默認允許在批量賦值中使用的參數,默認為 `false`。
* `config.action_controller.action_on_unpermitted_parameters`:發現禁止使用的參數時,寫入日志還是拋出異常(分別設為 `:log` 和 `:raise`)。在開發環境和測試環境中的默認值為 `:log`,在其他環境中的默認值為 `false`。
#### 3.8 3設置 Action Dispatch
* `config.action_dispatch.session_store`:設置存儲會話的方式,默認為 `:cookie_store`,其他可用值有:`:active_record_store`,`:mem_cache_store`,以及自定義類的名字。
* `config.action_dispatch.default_headers`:一個 Hash,設置響應的默認報頭。默認設定的報頭為:
```
config.action_dispatch.default_headers = {
'X-Frame-Options' => 'SAMEORIGIN',
'X-XSS-Protection' => '1; mode=block',
'X-Content-Type-Options' => 'nosniff'
}
```
* `config.action_dispatch.tld_length`:設置頂級域名(top-level domain,簡稱 TLD)的長度,默認為 `1`。
* `config.action_dispatch.http_auth_salt`:設置 HTTP Auth 認證的加鹽值,默認為 `'http authentication'`。
* `config.action_dispatch.signed_cookie_salt`:設置簽名 cookie 的加鹽值,默認為 `'signed cookie'`。
* `config.action_dispatch.encrypted_cookie_salt`:設置加密 cookie 的加鹽值,默認為 `'encrypted cookie'`。
* `config.action_dispatch.encrypted_signed_cookie_salt`:設置簽名加密 cookie 的加鹽值,默認為 `'signed encrypted cookie'`。
* `config.action_dispatch.perform_deep_munge`:設置是否在參數上調用 `deep_munge` 方法。詳情參閱“[Rails 安全指南](security.html#unsafe-query-generation)”一文。默認值為 `true`。
* `ActionDispatch::Callbacks.before`:設置在處理請求前運行的代碼塊。
* `ActionDispatch::Callbacks.to_prepare`:設置在 `ActionDispatch::Callbacks.before` 之后、處理請求之前運行的代碼塊。這個代碼塊在開發環境中的每次請求中都會運行,但在生產環境或 `cache_classes` 設為 `true` 的環境中只運行一次。
* `ActionDispatch::Callbacks.after`:設置處理請求之后運行的代碼塊。
#### 3.9 3設置 Action View
`config.action_view` 包含以下設置項:
* `config.action_view.field_error_proc`:設置用于生成 Active Record 表單錯誤的 HTML,默認為:
```
Proc.new do |html_tag, instance|
%Q(<div class="field_with_errors">#{html_tag}</div>).html_safe
end
```
* `config.action_view.default_form_builder`:設置默認使用的表單構造器。默認值為 `ActionView::Helpers::FormBuilder`。如果想讓表單構造器在程序初始化完成后加載(在開發環境中每次請求都會重新加載),可使用字符串形式。
* `config.action_view.logger`:接受一個實現了 Log4r 接口的類,或者使用默認的 `Logger` 類,用于寫入來自 Action View 的日志。設為 `nil` 禁用日志。
* `config.action_view.erb_trim_mode`:設置 ERB 使用的刪除空白模式,默認為 `'-'`,使用 `<%= -%>` 或 `<%= =%>` 時,刪除行尾的空白和換行。詳情參閱 [Erubis 的文檔](http://www.kuwata-lab.com/erubis/users-guide.06.html#topics-trimspaces)。
* `config.action_view.embed_authenticity_token_in_remote_forms`:設置啟用 `:remote => true` 選項的表單如何處理 `authenticity_token` 字段。默認值為 `false`,即不加入 `authenticity_token` 字段,有助于使用片段緩存緩存表單。遠程表單可從 `meta` 標簽中獲取認證權標,因此沒必要再加入 `authenticity_token` 字段,除非要支持沒啟用 JavaScript 的瀏覽器。如果要支持沒啟用 JavaScript 的瀏覽器,可以在表單的選項中加入 `:authenticity_token => true`,或者把這個設置設為 `true`。
* `config.action_view.prefix_partial_path_with_controller_namespace`:設置渲染命名空間中的控制器時是否要在子文件夾中查找局部視圖。例如,控制器名為 `Admin::PostsController`,渲染了以下視圖:
```
<%= render @post %>
```
這個設置的默認值為 `true`,渲染的局部視圖為 `/admin/posts/_post.erb`。如果設為 `false`,就會渲染 `/posts/_post.erb`,和沒加命名空間的控制器(例如 `PostsController`)行為一致。
* `config.action_view.raise_on_missing_translations`:找不到翻譯時是否拋出異常。
#### 3.10 3設置 Action Mailer
`config.action_mailer` 包含以下設置項:
* `config.action_mailer.logger`:接受一個實現了 Log4r 接口的類,或者使用默認的 `Logger` 類,用于寫入來自 Action Mailer 的日志。設為 `nil` 禁用日志。
* `config.action_mailer.smtp_settings`:詳細設置 `:smtp` 發送方式。接受一個 Hash,包含以下選項:
* `:address`:設置遠程郵件服務器,把默認值 `"localhost"` 改成所需值即可;
* `:port`:如果郵件服務器不使用端口 25,可通過這個選項修改;
* `:domain`:如果想指定一個 HELO 域名,可通過這個選項修改;
* `:user_name`:如果所用郵件服務器需要身份認證,可通過這個選項設置用戶名;
* `:password`:如果所用郵件服務器需要身份認證,可通過這個選項設置密碼;
* `:authentication`:如果所用郵件服務器需要身份認證,可通過這個選項指定認證類型,可選值包括:`:plain`,`:login`,`:cram_md5`;
* `config.action_mailer.sendmail_settings`:詳細設置 `sendmail` 發送方式。接受一個 Hash,包含以下選項:
* `:location`:`sendmail` 可執行文件的位置,默認為 `/usr/sbin/sendmail`;
* `:arguments`:傳入命令行的參數,默認為 `-i -t`;
* `config.action_mailer.raise_delivery_errors`:如果無法發送郵件,是否拋出異常。默認為 `true`。
* `config.action_mailer.delivery_method`:設置發送方式,默認為 `:smtp`。詳情參閱“Action Mailer 基礎”一文中的“[設置](action_mailer_basics.html#action-mailer-configuration)”一節。。
* `config.action_mailer.perform_deliveries`:設置是否真的發送郵件,默認為 `true`。測試時可設為 `false`。
* `config.action_mailer.default_options`:設置 Action Mailer 的默認選項。可設置各個郵件發送程序的 `from` 或 `reply_to` 等選項。默認值為:
```
mime_version: "1.0",
charset: "UTF-8",
content_type: "text/plain",
parts_order: ["text/plain", "text/enriched", "text/html"]
```
```
設置時要使用 Hash:
```
```
config.action_mailer.default_options = {
from: "noreply@example.com"
}
```
* `config.action_mailer.observers`:注冊郵件發送后觸發的監控器。
```
config.action_mailer.observers = ["MailObserver"]
```
* `config.action_mailer.interceptors`:注冊發送郵件前調用的攔截程序。
```
config.action_mailer.interceptors = ["MailInterceptor"]
```
#### 3.11 3設置 Active Support
Active Support 包含以下設置項:
* `config.active_support.bare`:啟動 Rails 時是否加載 `active_support/all`。默認值為 `nil`,即加載 `active_support/all`。
* `config.active_support.escape_html_entities_in_json`:在 JSON 格式的數據中是否轉義 HTML 實體。默認為 `false`。
* `config.active_support.use_standard_json_time_format`:在 JSON 格式的數據中是否把日期轉換成 ISO 8601 格式。默認為 `true`。
* `config.active_support.time_precision`:設置 JSON 編碼的時間精度,默認為 `3`。
* `ActiveSupport::Logger.silencer`:設為 `false` 可以靜默代碼塊中的日志消息。默認為 `true`。
* `ActiveSupport::Cache::Store.logger`:設置緩存存儲中使用的寫日志程序。
* `ActiveSupport::Deprecation.behavior`:作用和 `config.active_support.deprecation` 一樣,設置是否顯示 Rails 廢棄提醒。
* `ActiveSupport::Deprecation.silence`:接受一個代碼塊,靜默廢棄提醒。
* `ActiveSupport::Deprecation.silenced`:設置是否顯示廢棄提醒。
#### 3.12 3設置數據庫
幾乎每個 Rails 程序都要用到數據庫。數據庫信息可以在環境變量 `ENV['DATABASE_URL']` 中設定,也可在 `config/database.yml` 文件中設置。
在 `config/database.yml` 文件中可以設置連接數據庫所需的所有信息:
```
development:
adapter: postgresql
database: blog_development
pool: 5
```
上述設置使用 `postgresql` 適配器連接名為 `blog_development` 的數據庫。這些信息也可存儲在 URL 中,通過下面的環境變量提供:
```
> puts ENV['DATABASE_URL']
postgresql://localhost/blog_development?pool=5
```
`config/database.yml` 文件包含三個區域,分別對應 Rails 中的三個默認環境:
* `development` 環境在本地開發電腦上運行,手動與程序交互;
* `test` 環境用于運行自動化測試;
* `production` 環境用于部署后的程序;
如果需要使用 URL 形式,也可在 `config/database.yml` 文件中按照下面的方式設置:
```
development:
url: postgresql://localhost/blog_development?pool=5
```
`config/database.yml` 文件中可以包含 ERB 標簽 `<%= %>`。這個標簽中的代碼被視為 Ruby 代碼。使用 ERB 標簽可以從環境變量中獲取數據,或者計算所需的連接信息。
你無須手動更新數據庫設置信息。查看新建程序生成器,會發現一個名為 `--database` 的選項。使用這個選項可以從一組常用的關系型數據庫中選擇想用的數據庫。甚至還可重復執行生成器:`cd .. && rails new blog --database=mysql`。確認覆蓋文件 `config/database.yml` 后,程序就設置成使用 MySQL,而不是 SQLite。常用數據庫的設置如下所示。
#### 3.13 3連接設置
既然數據庫的連接信息有兩種設置方式,就要知道兩者之間的關系。
如果 `config/database.yml` 文件為空,而且設置了環境變量 `ENV['DATABASE_URL']`,Rails 就會使用環境變量連接數據庫:
```
$ cat config/database.yml
$ echo $DATABASE_URL
postgresql://localhost/my_database
```
如果 `config/database.yml` 文件存在,且沒有設置環境變量 `ENV['DATABASE_URL']`,Rails 會使用設置文件中的信息連接數據庫:
```
$ cat config/database.yml
development:
adapter: postgresql
database: my_database
host: localhost
$ echo $DATABASE_URL
```
如果有 `config/database.yml` 文件,也設置了環境變量 `ENV['DATABASE_URL']`,Rails 會合并二者提供的信息。下面舉個例子說明。
如果二者提供的信息有重復,環境變量中的信息優先級更高:
```
$ cat config/database.yml
development:
adapter: sqlite3
database: NOT_my_database
host: localhost
$ echo $DATABASE_URL
postgresql://localhost/my_database
$ rails runner 'puts ActiveRecord::Base.connections'
{"development"=>{"adapter"=>"postgresql", "host"=>"localhost", "database"=>"my_database"}}
```
這里的適配器、主機和數據庫名都和 `ENV['DATABASE_URL']` 中的信息一致。
如果沒有重復,則會從這兩個信息源獲取信息。如果有沖突,環境變量的優先級更高。
```
$ cat config/database.yml
development:
adapter: sqlite3
pool: 5
$ echo $DATABASE_URL
postgresql://localhost/my_database
$ rails runner 'puts ActiveRecord::Base.connections'
{"development"=>{"adapter"=>"postgresql", "host"=>"localhost", "database"=>"my_database", "pool"=>5}}
```
因為 `ENV['DATABASE_URL']` 中沒有提供數據庫連接池信息,所以從設置文件中獲取。二者都提供了 `adapter` 信息,但使用的是 `ENV['DATABASE_URL']` 中的信息。
如果完全不想使用 `ENV['DATABASE_URL']` 中的信息,要使用 `url` 子建指定一個 URL:
```
$ cat config/database.yml
development:
url: sqlite3://localhost/NOT_my_database
$ echo $DATABASE_URL
postgresql://localhost/my_database
$ rails runner 'puts ActiveRecord::Base.connections'
{"development"=>{"adapter"=>"sqlite3", "host"=>"localhost", "database"=>"NOT_my_database"}}
```
如上所示,`ENV['DATABASE_URL']` 中的連接信息被忽略了,使用了不同的適配器和數據庫名。
既然 `config/database.yml` 文件中可以使用 ERB,最好使用 `ENV['DATABASE_URL']` 中的信息連接數據庫。這種方式在生產環境中特別有用,因為我們并不想把數據庫密碼等信息納入版本控制系統(例如 Git)。
```
$ cat config/database.yml
production:
url: <%= ENV['DATABASE_URL'] %>
```
注意,這種設置方式很明確,只使用 `ENV['DATABASE_URL']` 中的信息。
##### 3.13.1 4設置 SQLite3 數據庫
Rails 內建支持 [SQLite3](http://www.sqlite.org)。SQLite 是個輕量級數據庫,無需單獨的服務器。大型線上環境可能并不適合使用 SQLite,但在開發環境和測試環境中使用卻很便利。新建程序時,Rails 默認使用 SQLite,但可以隨時換用其他數據庫。
下面是默認的設置文件(`config/database.yml`)中針對開發環境的數據庫設置:
```
development:
adapter: sqlite3
database: db/development.sqlite3
pool: 5
timeout: 5000
```
Rails 默認使用 SQLite3 存儲數據,因為 SQLite3 無需設置即可使用。Rails 還內建支持 MySQL 和 PostgreSQL。還提供了很多插件,支持更多的數據庫系統。如果在生產環境中使用了數據庫,Rails 很可能已經提供了對應的適配器。
##### 3.13.2 4設置 MySQL 數據庫
如果不想使用 SQLite3,而是使用 MySQL,`config/database.yml` 文件的內容會有些不同。下面是針對開發環境的設置:
```
development:
adapter: mysql2
encoding: utf8
database: blog_development
pool: 5
username: root
password:
socket: /tmp/mysql.sock
```
如果開發電腦中的 MySQL 使用 root 用戶,且沒有密碼,可以直接使用上述設置。否則就要相應的修改用戶名和密碼。
##### 3.13.3 4設置 PostgreSQL 數據庫
如果選擇使用 PostgreSQL,`config/database.yml` 會準備好連接 PostgreSQL 數據庫的信息:
```
development:
adapter: postgresql
encoding: unicode
database: blog_development
pool: 5
username: blog
password:
```
`PREPARE` 語句可使用下述方法禁用:
```
production:
adapter: postgresql
prepared_statements: false
```
##### 3.13.4 4在 JRuby 平臺上設置 SQLite3 數據庫
如果在 JRuby 中使用 SQLite3,`config/database.yml` 文件的內容會有點不同。下面是針對開發環境的設置:
```
development:
adapter: jdbcsqlite3
database: db/development.sqlite3
```
##### 3.13.5 4在 JRuby 平臺上設置 MySQL 數據庫
如果在 JRuby 中使用 MySQL,`config/database.yml` 文件的內容會有點不同。下面是針對開發環境的設置:
```
development:
adapter: jdbcmysql
database: blog_development
username: root
password:
```
##### 3.13.6 4在 JRuby 平臺上設置 PostgreSQL 數據庫
如果在 JRuby 中使用 PostgreSQL,`config/database.yml` 文件的內容會有點不同。下面是針對開發環境的設置:
```
development:
adapter: jdbcpostgresql
encoding: unicode
database: blog_development
username: blog
password:
```
請相應地修改 `development` 區中的用戶名和密碼。
#### 3.14 3新建 Rails 環境
默認情況下,Rails 提供了三個環境:開發,測試和生產。這三個環境能滿足大多數需求,但有時需要更多的環境。
假設有個服務器鏡像了生產環境,但只用于測試。這種服務器一般叫做“交付準備服務器”(staging server)。要想為這個服務器定義一個名為“staging”的環境,新建文件 `config/environments/staging.rb` 即可。請使用 `config/environments` 文件夾中的任一文件作為模板,以此為基礎修改設置。
新建的環境和默認提供的環境沒什么區別,可以執行 `rails server -e staging` 命令啟動服務器,執行 `rails console staging` 命令進入控制臺,`Rails.env.staging?` 也可使用。
#### 3.15 3部署到子目錄中
默認情況下,Rails 在根目錄(例如 `/`)中運行程序。本節說明如何在子目錄中運行程序。
假設想把網站部署到 `/app1` 目錄中。生成路由時,Rails 要知道這個目錄:
```
config.relative_url_root = "/app1"
```
或者,設置環境變量 `RAILS_RELATIVE_URL_ROOT` 也行。
這樣設置之后,Rails 生成的鏈接都會加上前綴 `/app1`。
##### 3.15.1 4使用 Passenger
使用 Passenger 時,在子目錄中運行程序更簡單。具體做法參見 [Passenger 手冊](http://www.modrails.com/documentation/Users%20guide%20Apache.html#deploying_rails_to_sub_uri)。
##### 3.15.2 4使用反向代理
TODO
##### 3.15.3 4部署到子目錄時的注意事項
在生產環境中部署到子目錄中會影響 Rails 的多個功能:
* 開發環境
* 測試環境
* 伺服靜態資源文件
* Asset Pipeline
### 4 Rails 環境設置
Rails 的某些功能只能通過外部的環境變量設置。下面介紹的環境變量可以被 Rails 識別:
* `ENV["RAILS_ENV"]`:指定 Rails 運行在哪個環境中:生成環境,開發環境,測試環境等。
* `ENV["RAILS_RELATIVE_URL_ROOT"]`:[部署到子目錄](#deploy-to-a-subdirectory-relative-url-root)時,路由用來識別 URL。
* `ENV["RAILS_CACHE_ID"]` 和 `ENV["RAILS_APP_VERSION"]`:用于生成緩存擴展鍵。允許在同一程序中使用多個緩存。
### 5 使用初始化腳本
加載完框架以及程序中使用的 gem 后,Rails 會加載初始化腳本。初始化腳本是個 Ruby 文件,存儲在程序的 `config/initializers` 文件夾中。初始化腳本可在框架和 gem 加載完成后做設置。
如果有需求,可以使用子文件夾組織初始化腳本,Rails 會加載整個 `config/initializers` 文件夾中的內容。
如果對初始化腳本的加載順序有要求,可以通過文件名控制。初始化腳本的加載順序按照文件名的字母表順序進行。例如,`01_critical.rb` 在 `02_normal.rb` 之前加載。
### 6 初始化事件
Rails 提供了 5 個初始化事件,可做鉤子使用。下面按照事件的加載順序介紹:
* `before_configuration`:程序常量繼承自 `Rails::Application` 之后立即運行。`config` 方法在此事件之前調用。
* `before_initialize`:在程序初始化過程中的 `:bootstrap_hook` 之前運行,接近初始化過程的開頭。
* `to_prepare`:所有 Railtie(包括程序本身)的初始化都運行完之后,但在按需加載代碼和構建中間件列表之前運行。更重要的是,在開發環境中,每次請求都會運行,但在生產環境和測試環境中只運行一次(在啟動階段)。
* `before_eager_load`:在按需加載代碼之前運行。這是在生產環境中的默認表現,但在開發環境中不是。
* `after_initialize`:在程序初始化完成之后運行,即 `config/initializers` 文件夾中的初始化腳本運行完畢之后。
要想為這些鉤子定義事件,可以在 `Rails::Application`、`Rails::Railtie` 或 `Rails::Engine` 的子類中使用代碼塊:
```
module YourApp
class Application < Rails::Application
config.before_initialize do
# initialization code goes here
end
end
end
```
或者,在 `Rails.application` 對象上調用 `config` 方法:
```
Rails.application.config.before_initialize do
# initialization code goes here
end
```
程序的某些功能,尤其是路由,在 `after_initialize` 之后還不可用。
#### 6.1 3`Rails::Railtie#initializer`
Rails 中有幾個初始化腳本使用 `Rails::Railtie` 的 `initializer` 方法定義,在程序啟動時運行。下面這段代碼摘自 Action Controller 中的 `set_helpers_path` 初始化腳本:
```
initializer "action_controller.set_helpers_path" do |app|
ActionController::Helpers.helpers_path = app.helpers_paths
end
```
`initializer` 方法接受三個參數,第一個是初始化腳本的名字,第二個是選項 Hash(上述代碼中沒用到),第三個參數是代碼塊。參數 Hash 中的 `:before` 鍵指定在特定的初始化腳本之前運行,`:after` 鍵指定在特定的初始化腳本之后運行。
使用 `initializer` 方法定義的初始化腳本按照定義的順序運行,但指定 `:before` 或 `:after` 參數的初始化腳本例外。
初始化腳本可放在任一初始化腳本的前面或后面,只要符合邏輯即可。假設定義了四個初始化腳本,名字為 `"one"` 到 `"four"`(就按照這個順序定義),其中 `"four"` 在 `"four"` 之前,且在 `"three"` 之后,這就不符合邏輯,Rails 無法判斷初始化腳本的加載順序。
`initializer` 方法的代碼塊參數是程序實例,因此可以調用 `config` 方法,如上例所示。
因為 `Rails::Application` 直接繼承自 `Rails::Railtie`,因此可在文件 `config/application.rb` 中使用 `initializer` 方法定義程序的初始化腳本。
#### 6.2 3初始化腳本
下面列出了 Rails 中的所有初始化腳本,按照定義的順序,除非特別說明,也按照這個順序執行。
* `load_environment_hook`:只是一個占位符,讓 `:load_environment_config` 在其前運行。
* `load_active_support`:加載 `active_support/dependencies`,加入 Active Support 的基礎。如果 `config.active_support.bare` 為非真值(默認),還會加載 `active_support/all`。
* `initialize_logger`:初始化日志程序(`ActiveSupport::Logger` 對象),可通過 `Rails.logger` 調用。在此之前的初始化腳本中不能定義 `Rails.logger`。
* `initialize_cache`:如果還沒創建 `Rails.cache`,使用 `config.cache_store` 指定的方式初始化緩存,并存入 `Rails.cache`。如果對象能響應 `middleware` 方法,對應的中間件會插入 `Rack::Runtime` 之前。
* `set_clear_dependencies_hook`:為 `active_record.set_dispatch_hooks` 提供鉤子,在本初始化腳本之前運行。這個初始化腳本只有當 `cache_classes` 為 `false` 時才會運行,使用 `ActionDispatch::Callbacks.after` 從對象空間中刪除請求過程中已經引用的常量,以便下次請求重新加載。
* `initialize_dependency_mechanism`:如果 `config.cache_classes` 為 `true`,設置 `ActiveSupport::Dependencies.mechanism` 使用 `require` 而不是 `load` 加載依賴件。
* `bootstrap_hook`:運行所有 `before_initialize` 代碼塊。
* `i18n.callbacks`:在開發環境中,設置一個 `to_prepare` 回調,調用 `I18n.reload!` 加載上次請求后修改的本地化翻譯。在生產環境中這個回調只會在首次請求時運行。
* `active_support.deprecation_behavior`:設置各環境的廢棄提醒方式,開發環境的方式為 `:log`,生產環境的方式為 `:notify`,測試環境的方式為 `:stderr`。如果沒有為 `config.active_support.deprecation` 設定值,這個初始化腳本會提醒用戶在當前環境的設置文件中設置。可以設為一個數組。
* `active_support.initialize_time_zone`:根據 `config.time_zone` 設置程序的默認時區,默認值為 `"UTC"`。
* `active_support.initialize_beginning_of_week`:根據 `config.beginning_of_week` 設置程序默認使用的一周開始日,默認值為 `:monday`。
* `action_dispatch.configure`:把 `ActionDispatch::Http::URL.tld_length` 設置為 `config.action_dispatch.tld_length` 指定的值。
* `action_view.set_configs`:根據 `config.action_view` 設置 Action View,把指定的方法名做為賦值方法發送給 `ActionView::Base`,并傳入指定的值。
* `action_controller.logger`:如果還未創建,把 `ActionController::Base.logger` 設為 `Rails.logger`。
* `action_controller.initialize_framework_caches`:如果還未創建,把 `ActionController::Base.cache_store` 設為 `Rails.cache`。
* `action_controller.set_configs`:根據 `config.action_controller` 設置 Action Controller,把指定的方法名作為賦值方法發送給 `ActionController::Base`,并傳入指定的值。
* `action_controller.compile_config_methods`:初始化指定的設置方法,以便快速訪問。
* `active_record.initialize_timezone`:把 `ActiveRecord::Base.time_zone_aware_attributes` 設為 `true`,并把 `ActiveRecord::Base.default_timezone` 設為 UTC。從數據庫中讀取數據時,轉換成 `Time.zone` 中指定的時區。
* `active_record.logger`:如果還未創建,把 `ActiveRecord::Base.logger` 設為 `Rails.logger`。
* `active_record.set_configs`:根據 `config.active_record` 設置 Active Record,把指定的方法名作為賦值方法傳給 `ActiveRecord::Base`,并傳入指定的值。
* `active_record.initialize_database`:從 `config/database.yml` 中加載數據庫設置信息,并為當前環境建立數據庫連接。
* `active_record.log_runtime`:引入 `ActiveRecord::Railties::ControllerRuntime`,這個模塊負責把 Active Record 查詢花費的時間寫入日志。
* `active_record.set_dispatch_hooks`:如果 `config.cache_classes` 為 `false`,重置所有可重新加載的數據庫連接。
* `action_mailer.logger`:如果還未創建,把 `ActionMailer::Base.logger` 設為 `Rails.logger`。
* `action_mailer.set_configs`:根據 `config.action_mailer` 設置 Action Mailer,把指定的方法名作為賦值方法發送給 `ActionMailer::Base`,并傳入指定的值。
* `action_mailer.compile_config_methods`:初始化指定的設置方法,以便快速訪問。
* `set_load_path`:在 `bootstrap_hook` 之前運行。把 `vendor` 文件夾、`lib` 文件夾、`app` 文件夾中的所有子文件夾,以及 `config.load_paths` 中指定的路徑加入 `$LOAD_PATH`。
* `set_autoload_paths`:在 `bootstrap_hook` 之前運行。把 `app` 文件夾中的所有子文件夾,以及 `config.autoload_paths` 指定的路徑加入 `ActiveSupport::Dependencies.autoload_paths`。
* `add_routing_paths`:加載所有 `config/routes.rb` 文件(程序中的,Railtie 中的,以及引擎中的),并創建程序的路由。
* `add_locales`:把 `config/locales` 文件夾中的所有文件(程序中的,Railties 中的,以及引擎中的)加入 `I18n.load_path`,讓這些文件中的翻譯可用。
* `add_view_paths`:把程序、Railtie 和引擎中的 `app/views` 文件夾加入視圖文件查找路徑。
* `load_environment_config`:加載 `config/environments` 文件夾中當前環境對應的設置文件。
* `append_asset_paths`:查找程序的靜態資源文件路徑,Railtie 中的靜態資源文件路徑,以及 `config.static_asset_paths` 中可用的文件夾。
* `prepend_helpers_path`:把程序、Railtie、引擎中的 `app/helpers` 文件夾加入幫助文件查找路徑。
* `load_config_initializers`:加載程序、Railtie、引擎中 `config/initializers` 文件夾里所有的 Ruby 文件。這些文件可在框架加載后做設置。
* `engines_blank_point`:在初始化過程加入一個時間點,以防加載引擎之前要做什么處理。在這一點之后,會運行所有 Railtie 和引擎的初始化腳本。
* `add_generator_templates`:在程序、Railtie、引擎的 `lib/templates` 文件夾中查找生成器使用的模板,并把這些模板添加到 `config.generators.templates`,讓所有生成器都能使用。
* `ensure_autoload_once_paths_as_subset`:確保 `config.autoload_once_paths` 只包含 `config.autoload_paths` 中的路徑。如果包含其他路徑,會拋出異常。
* `add_to_prepare_blocks`:把程序、Railtie、引擎中的 `config.to_prepare` 加入 Action Dispatch 的 `to_prepare` 回調中,這些回調在開發環境中每次請求都會運行,但在生產環境中只在首次請求前運行。
* `add_builtin_route`:如果程序運行在開發環境中,這個初始化腳本會把 `rails/info/properties` 添加到程序的路由中。這個路由對應的頁面顯示了程序的詳細信息,例如 Rails 和 Ruby 版本。
* `build_middleware_stack`:構建程序的中間件列表,返回一個對象,可響應 `call` 方法,參數為 Rack 請求的環境對象。
* `eager_load!`:如果 `config.eager_load` 為 `true`,運行 `config.before_eager_load` 鉤子,然后調用 `eager_load!`,加載所有 `config.eager_load_namespaces` 中的命名空間。
* `finisher_hook`:為程序初始化完成點提供一個鉤子,還會運行程序、Railtie、引擎中的所有 `config.after_initialize` 代碼塊。
* `set_routes_reloader`:設置 Action Dispatch 使用 `ActionDispatch::Callbacks.to_prepare` 重新加載路由文件。
* `disable_dependency_loading`:如果 `config.eager_load` 為 `true`,禁止自動加載依賴件。
### 7 數據庫連接池
Active Record 數據庫連接由 `ActiveRecord::ConnectionAdapters::ConnectionPool` 管理,確保一個連接池的線程量限制在有限的數據庫連接數之內。這個限制量默認為 5,但可以在文件 `database.yml` 中設置。
```
development:
adapter: sqlite3
database: db/development.sqlite3
pool: 5
timeout: 5000
```
因為連接池在 Active Record 內部處理,因此程序服務器(Thin,mongrel,Unicorn 等)要表現一致。一開始數據庫連接池是空的,然后按需創建更多的鏈接,直到達到連接池數量限制為止。
任何一個請求在初次需要連接數據庫時都要檢查連接,請求處理完成后還會再次檢查,確保后續連接可使用這個連接池。
如果嘗試使用比可用限制更多的連接,Active Record 會阻塞連接,等待連接池分配新的連接。如果無法獲得連接,會拋出如下所示的異常。
```
ActiveRecord::ConnectionTimeoutError - could not obtain a database connection within 5 seconds. The max pool size is currently 5; consider increasing it:
```
如果看到以上異常,可能需要增加連接池限制數量,方法是修改 `database.yml` 文件中的 `pool` 選項。
如果在多線程環境中運行程序,有可能多個線程同時使用多個連接。所以,如果程序的請求量很大,有可能出現多個線程搶用有限的連接。
### 反饋
歡迎幫忙改善指南質量。
如發現任何錯誤,歡迎修正。開始貢獻前,可先行閱讀[貢獻指南:文檔](http://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html#contributing-to-the-rails-documentation)。
翻譯如有錯誤,深感抱歉,歡迎 [Fork](https://github.com/ruby-china/guides/fork) 修正,或至此處[回報](https://github.com/ruby-china/guides/issues/new)。
文章可能有未完成或過時的內容。請先檢查 [Edge Guides](http://edgeguides.rubyonrails.org) 來確定問題在 master 是否已經修掉了。再上 master 補上缺少的文件。內容參考 [Ruby on Rails 指南準則](ruby_on_rails_guides_guidelines.html)來了解行文風格。
最后,任何關于 Ruby on Rails 文檔的討論,歡迎到 [rubyonrails-docs 郵件群組](http://groups.google.com/group/rubyonrails-docs)。
- Ruby on Rails 指南 (651bba1)
- 入門
- Rails 入門
- 模型
- Active Record 基礎
- Active Record 數據庫遷移
- Active Record 數據驗證
- Active Record 回調
- Active Record 關聯
- Active Record 查詢
- 視圖
- Action View 基礎
- Rails 布局和視圖渲染
- 表單幫助方法
- 控制器
- Action Controller 簡介
- Rails 路由全解
- 深入
- Active Support 核心擴展
- Rails 國際化 API
- Action Mailer 基礎
- Active Job 基礎
- Rails 程序測試指南
- Rails 安全指南
- 調試 Rails 程序
- 設置 Rails 程序
- Rails 命令行
- Rails 緩存簡介
- Asset Pipeline
- 在 Rails 中使用 JavaScript
- 引擎入門
- Rails 應用的初始化過程
- Autoloading and Reloading Constants
- 擴展 Rails
- Rails 插件入門
- Rails on Rack
- 個性化Rails生成器與模板
- Rails應用模版
- 貢獻 Ruby on Rails
- Contributing to Ruby on Rails
- API Documentation Guidelines
- Ruby on Rails Guides Guidelines
- Ruby on Rails 維護方針
- 發布記
- A Guide for Upgrading Ruby on Rails
- Ruby on Rails 4.2 發布記
- Ruby on Rails 4.1 發布記
- Ruby on Rails 4.0 Release Notes
- Ruby on Rails 3.2 Release Notes
- Ruby on Rails 3.1 Release Notes
- Ruby on Rails 3.0 Release Notes
- Ruby on Rails 2.3 Release Notes
- Ruby on Rails 2.2 Release Notes