簡體   English   中英

Rails respond_with:它是如何工作的?

[英]Rails respond_with: how does it work?

我一直在這里和那里閱讀關於 Rails 3 中的respond_with方法有多酷。但我什至在 Rails API 或搜索源代碼中都找不到對它的引用。 任何人都可以向我解釋它是如何工作的(您可以使用哪些選項等),或者將我指向它實際實現的位置,以便我可以自己仔細閱讀代碼?

Rails 4.2+ 更新

#respond_with::respond_tonb class 方法)不再是 Rails 的一部分 從 Rails 4.2 開始,它們被遷移到第三方響應者gem( 發布說明/2014 年 8 月提交)。 雖然響應者默認不包含在 Rails 中,但它是 Devise 的依賴項,因此可在許多 Rails 應用程序中使用。

然而, #respond_to實例方法仍然是 Rails 的一部分(撰寫本文時為 5.2rc1)。

ActionController::MimeResponds的官方 Rails API 文檔解釋了#respond_to工作原理。 #respond_with::respond_to的原始 Rails Guides 文檔注釋仍然可以在響應者 gem 源代碼中找到。


原始答案

響應者的代碼基於 class 和模塊。 包含在ActionController::Base中的MimeResponds ,class 您的ApplicationController繼承自。 然后是ActionController::Responder ,它在使用 respond_with 時提供默認行為。


默認情況下,rails 在響應中提供的唯一行為是隱式嘗試呈現具有與操作匹配的名稱的模板。 除此之外的任何事情都需要操作中的更多指令,或者使用塊來處理多種格式響應的自定義 respond_to 調用。

由於大多數控制器使用相當常見的定制模式,響應者通過引入更多默認行為來提供額外的抽象級別。 讀取特定格式的調用 to_xml/to_json 的操作,以及提供相同格式的變更操作以及成功的變更操作的重定向。


有一些機會可以自定義響應者的行為方式,從細微的調整到完全覆蓋或擴展行為。

Class 級別: respond_to

您可以在此處指定響應程序應處理的格式。 這些格式可以自定義它們將應用於哪些操作。 每種格式都可以通過單獨的調用來指定,從而可以完全自定義每種格式的操作。

# Responds to html and json on all actions
respond_to :html, :json

# Responds to html and json on index and show actions only.
respond_to :html, :json, :only => [:index,:show]

# Responds to html for everything except show, and json only for index, create and update
respond_to :html, :except => [:show]
respond_to :json, :only => [:index, :create, :update]

Class 級別: responder

這是一個包含響應者的 class 屬性。 這可以是響應調用的任何內容,這意味着您可以使用響應調用的 proc/lambda 或 class。 另一種選擇是將一個或多個模塊混合到現有響應程序中以重載現有方法,從而增強默認行為。

class SomeController < ApplicationController
  respond_to :json

  self.responder = proc do |controller, resources, options|
    resource = resources.last
    request = controller.request
    if request.get?
      controller.render json: resource
    elsif request.post? or request.put?
      if resource.errors.any?
        render json: {:status => 'failed', :errors => resource.errors}
      else
        render json: {:status => 'created', :object => resource}
      end
    end
  end
end

雖然可能有一些有趣的邊緣用例,但將模塊擴展或混合到默認響應者中更有可能是更常見的模式。 在任何情況下,相關的選項都是資源和選項,因為它們是從 from respond_with 傳遞過來的。

實例級別: respond_with

這里的選項是那些將被傳遞給 controller 中的 render 或 redirect_to 的選項,但它們僅包含在成功場景中。 對於 GET 操作,這些將是渲染調用,對於其他操作,這將是重定向的選項。 其中最有用的可能是:location選項,它可用於覆蓋該重定向路徑,以防 respond_with 的 arguments 不足以構建正確的 URL。

# These two are essentially equal
respond_with(:admin, @user, @post)
respond_with(@post, :location => admin_user_post(@user, @post)

# Respond with a 201 instead of a 200 HTTP status code, and also
# redirect to the collection path instead of the resource path
respond_with(@post, :status => :created, :location => posts_path)

# Note that if you want to pass a URL with a query string
# then the location option would be needed.
# /users?scope=active
respond_with(@user, :location => users_path(:scope => 'active'))

作為替代方案,響應者gem 不僅提供了一些模塊來覆蓋一些默認行為。 它使用擴展默認響應器的匿名 class 覆蓋默認響應器,並提供 class 級別的方法來混合自定義模塊到此 class。 這里最有用的是 flash 響應程序,它提供了一組默認的 flash,將自定義委托給 I18n 系統,默認為config/locales/en.yml

我在以前的項目中使用的一些自定義響應器示例包括一個響應器,它自動修飾我的資源,並提供一組默認的頁面標題和一個用於輕松自定義或覆蓋頁面標題的界面。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM