Porsche Cayenne買不起
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Help
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    --- title: Rails Guides description: Ruby on Rails 官方指南 tags: Rails Guides --- [Rails Guides](/XS5U4U9XQ5WSg4kYklEajQ) === Ruby on Rails Guides (v6.1.4) These are the new guides for Rails 6.1 based on v6.1.4. These guides are designed to make you immediately productive with Rails, and to help you understand how all of the pieces fit together. The guides for earlier releases: Rails 6.0, Rails 5.2, Rails 5.1, Rails 5.0, Rails 4.2, Rails 4.1, Rails 4.0, Rails 3.2, Rails 3.1, Rails 3.0, and Rails 2.3. ## [Rails Internationalization (I18n) API](/0PUd3sHXSMi7Sh8DROL8Yg) ## [Rails on Rack](/V1XyMhOnT0698C-y1gyl7g) 本篇介紹 Rails 與 Rack 的整合、如何與其他 Rack 組件互動。 :heavy_check_mark: 如何在 Rails 中使用 Rack [Middleware](https://ithelp.ithome.com.tw/articles/10203041) :heavy_check_mark: Action Pack 的內部 Middleware stack :heavy_check_mark: 如何自定 Middleware stack :::danger 本指南假定您已經了解 Rack 協定和相關概念,例如 middleware、URL maps 和 `Rack::Builder` ::: ## [1. Rack 介紹](https://guides.rubyonrails.org/rails_on_rack.html#introduction-to-rack) Rack 為使用 Ruby 開發的網路應用程序提供了一個最小化、模組化和容易介接的介面(interface)。 Rack 將 HTTP requests 和 responses 包裝成最簡單的形式,它替 Web servers、Web 框架和兩者之間的軟體(也就是 middleware)所使用的 API,統一並提取為單一個方法來調用。 更多內容請參考:[Rack API 文件](https://rack.github.io/) 解釋 Rack 的運作原理並不在此章節的範圍中,若您對基礎的 Rack 知識還並不熟悉,請先參考[線上資源](#4-線上資源)。 ## [2. Rails on Rack](https://guides.rubyonrails.org/rails_on_rack.html#rails-on-rack) ### [2.1 Rails Application's Rack Object](https://guides.rubyonrails.org/rails_on_rack.html#rails-application-s-rack-object) `Rails.application` 是 Rails application 中主要的 Rack application object。 任何符合 Rack 規範的 web server 都應該使用 `Rails.application` object 來執行 Rails application。 ### [2.2 bin/rails server](https://guides.rubyonrails.org/rails_on_rack.html#bin-rails-server) `bin/rails server` 做最基本的工作,建立一個 `Rack::Server` object 並開啟 web server `bin/rails server` 如何建立 `Rack::Server` 實體: ```ruby Rails::Server.new.tap do |server| require APP_PATH Dir.chdir(Rails.application.root) server.start end ``` `Rails::Server` 繼承自 `Rack::Server` 並且呼叫 `Rack::Server#start` 方法: ```ruby class Server < ::Rack::Server def start # ... super end end ``` ### [2.3 rackup](https://guides.rubyonrails.org/rails_on_rack.html#rackup) 要以 `rackup` 取代 `bin/rails server`,您可以將下方的程式碼放進 Rails application 根目錄內的 `config.ru`: ```ruby # Rails.root/config.ru require_relative "config/environment" run Rails.application ``` 開啟 server: ```bash $ rackup config.ru ``` 獲得更多 `rackup` 選項: ```bash $ rackup --help ``` ### [2.4 開發與自動重新加載](https://guides.rubyonrails.org/rails_on_rack.html#development-and-auto-reloading) Middleware 只會加載一次,並且不會監控更動。 您必須重新啟動 server 才能將更動反映在運行的應用程序中。 ## [3. Action Dispatcher Middleware Stack](https://guides.rubyonrails.org/rails_on_rack.html#action-dispatcher-middleware-stack) 許多 Action Dispatcher 的內部組件是以 Rack middleware 實作的。 `Rails::Application` 使用 `ActionDispatch::MiddlewareStack` 將各種內外部 middlewares 組合起來,形成一個完整的 Rails Rack application。 :::warning `ActionDispatch::MiddlewareStack` 等同於 Rails 的 `Rack::Builder`,但它的構建是為了更好的靈活性和更多的特性來滿足 Rails 的需求。 ::: ### [3.1 Inspecting Middleware Stack](https://guides.rubyonrails.org/rails_on_rack.html#inspecting-middleware-stack) Rails 有一個方便的命令可用來檢視使用中的 middleware stack: ```bash $ bin/rails middleware ``` 對於新生成的 Rails application,可能會有如下結果: ```ruby use Rack::Sendfile use ActionDispatch::Static use ActionDispatch::Executor use ActiveSupport::Cache::Strategy::LocalCache::Middleware use Rack::Runtime use Rack::MethodOverride use ActionDispatch::RequestId use ActionDispatch::RemoteIp use Sprockets::Rails::QuietAssets use Rails::Rack::Logger use ActionDispatch::ShowExceptions use WebConsole::Middleware use ActionDispatch::DebugExceptions use ActionDispatch::ActionableExceptions use ActionDispatch::Reloader use ActionDispatch::Callbacks use ActiveRecord::Migration::CheckPending use ActionDispatch::Cookies use ActionDispatch::Session::CookieStore use ActionDispatch::Flash use ActionDispatch::ContentSecurityPolicy::Middleware use Rack::Head use Rack::ConditionalGet use Rack::ETag use Rack::TempfileReaper run MyApp::Application.routes ``` 此處顯示的預設 middlewares (包含其他),均在下面的 [Internal Middlewares](#33-內部-Middleware-Stack) 部分進行總結。 ### [3.2 設置 Middleware Stack](https://guides.rubyonrails.org/rails_on_rack.html#configuring-middleware-stack) Rails 提供了一個簡單的配置介面(configaration interface) `config.middleware`,其透過 `application.rb` 或環境配置檔案 `environment/<environment>.rb`,來添加、刪除和修改在 middleware stack 中的 middlewares。 #### [3.2.1 添加 Middleware](https://guides.rubyonrails.org/rails_on_rack.html#adding-a-middleware) 您可使用以下方法來將新的 middleware 添加至 middleware stack 中: - `config.middleware.use(new_middleware, args)` 將新的 middleware 添加至 middleware statck 最尾端。 - `config.middleware.insert_before(existing_middleware, new_middleware, args)` 將新的 middleware 添加至指定 middleware 的前方。 - `config.middleware.insert_after(existing_middleware, new_middleware, args)` 將新的 middleware 添加至指定 middleware 的後方。 ```ruby=! # config/application.rb # Push Rack::BounceFavicon at the bottom config.middleware.use Rack::BounceFavicon # Add Lifo::Cache after ActionDispatch::Executor. # Pass { page_cache: false } argument to Lifo::Cache. config.middleware.insert_after ActionDispatch::Executor, Lifo::Cache, page_cache: false ``` #### [3.2.2 替換 Middleware](https://guides.rubyonrails.org/rails_on_rack.html#swapping-a-middleware) 您可使用 `config.middleware.swap` 來替換 middleware stack 中存在的 middleware。 ```ruby # config/application.rb # Replace ActionDispatch::ShowExceptions with Lifo::ShowExceptions config.middleware.swap ActionDispatch::ShowExceptions, Lifo::ShowExceptions ``` #### [3.2.3 刪除 Middleware](https://guides.rubyonrails.org/rails_on_rack.html#deleting-a-middleware) 將下方的程式碼添加至您的設置當中: ```ruby # config/application.rb config.middleware.delete Rack::Runtime ``` 現在您可以檢視 middleware stack,您會發現 `Rack::Runtime` 並不在其中: ```bash $ bin/rails middleware (in /Users/lifo/Rails/blog) use ActionDispatch::Static use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x00000001c304c8> ... run Rails.application.routes ``` 若您想要移除與 session 相關的 middleware,請參考下方程式碼: ```ruby # config/application.rb config.middleware.delete ActionDispatch::Cookies config.middleware.delete ActionDispatch::Session::CookieStore config.middleware.delete ActionDispatch::Flash ``` 以及移除瀏覽器相關的 middleware: ```ruby # config/application.rb config.middleware.delete Rack::MethodOverride ``` ### [3.3 內部 Middleware Stack](https://guides.rubyonrails.org/rails_on_rack.html#internal-middleware-stack) Action Controller 中的大部分功能都是經由 middlewares 實作的。 下方列表解釋了它們中的每一個的目的: `Rack::Sendfile` - 設置 server 特定的 X-Sendfile header。 透過 `config.action_dispatch.x_sendfile_header` 選項設置。 `ActionDispatch::Static` - 用於從公共目錄中提供靜態文件。 如果 `config.public_file_server.enabled` 為 `false`,則禁用。 `Rack::Lock` - 將 `env["rack.multithread"]` 設置為 `false`,並將 application 包裝在互斥鎖(Mutex)中。 `ActionDispatch::Executor` - 用於開發期間執行緒安全(thread safe)的重新加載程式碼。 `ActiveSupport::Cache::Strategy::LocalCache::Middleware` - 用於記憶緩存(cache)。此緩存不是執行緒安全的。 `Rack::Runtime` - 設置 X-Runtime header,其中包含執行 reqeust 時所用的時間(以秒為單位)。 `Rack::MethodOverride` - 如果設置了 `params[:_method]`,則允許覆蓋該方法。 該 middleware 這是支援 PUT 和 DELETE HTTP 方法。 `ActionDispatch::RequestId` - 為 response 提供唯一的 `X-Request-Id` header,用於啟用 `ActionDispatch::Request#request_id` 方法。 `ActionDispatch::RemoteIp` - 檢查 IP 詐騙(spoofing)攻擊。 `Sprockets::Rails::QuietAssets` - 禁止輸出 asset requests 的 logger。 `Rails::Rack::Logger` - 通知 logs request 已經開始。 request 完成後,刷新所有 logs。 `ActionDispatch::ShowExceptions` - rescue 任何 application 回傳的 exception,並且呼叫以最終用戶的格式包裝的 exceptions app。 `ActionDispatch::DebugExceptions` - 負責記錄 exceptions,如果 request 來自本機,則顯示 debugging 頁面。 `ActionDispatch::ActionableExceptions` - 提供一種從 Rails 錯誤頁面調度操作(dispatch actions)的方法 `ActionDispatch::Reloader` - 提供準備和清理 callback,旨在開發期間幫助重新加載程式碼。 `ActionDispatch::Callbacks` - 提供要在分派 request 前後執行的 callback。 `ActiveRecord::Migration::CheckPending` - 檢查 pending migrations 並在有任何 migrations 處在 pending 狀態時 raise `ActiveRecord::PendingMigrationError`。 `ActionDispatch::Cookies` - 為 reqeust 設置 cookies。 `ActionDispatch::Session::CookieStore` - 負責將 session 存儲在 cookie 中。 `ActionDispatch::Flash` - 設置 flash keys。只有在 `config.action_controller.session_store` 設置被設定為 value 時才可使用。 `ActionDispatch::ContentSecurityPolicy::Middleware` - 提供 DSL 以配置 Content-Security-Policy header。 `Rack::Head` - 將 HEAD requests 轉換為 `GET` requests 並為它們提供服務。 `Rack::ConditionalGet` - 添加對 "Conditional `GET`" 的支援,以便在頁面未改動時 server 不會回應任何內容。 `Rack::ETag` - 在所有字串上添加 ETag header。 ETag 用於驗證緩存(cache)。 `Rack::TempfileReaper` - 清理用於緩衝多部分請求(buffer multipart requests)的臨時檔案(tempfiles)。 :::info 可以在您自定義的 Rack stack 中任意使用上述 middlewares。 ::: ## [4. 線上資源](https://guides.rubyonrails.org/rails_on_rack.html#resources) ### [4.1 Learning Rack](https://guides.rubyonrails.org/rails_on_rack.html#learning-rack) - [Official Rack Website](https://rack.github.io/) - [Introducing Rack](http://chneukirchen.org/blog/archive/2007/02/introducing-rack.html) ### [4.2 Understanding Middlewares](https://guides.rubyonrails.org/rails_on_rack.html#understanding-middlewares) - [Railscast on Rack Middlewares](http://railscasts.com/episodes/151-rack-middleware)

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully