Rails answer_with: nó hoạt động như thế nào?


128

Tôi đã đọc ở đây và ở đó về mức độ tuyệt vời của respond_withphương thức trong Rails 3. Nhưng tôi thậm chí không thể tìm thấy một tham chiếu đến nó trong API Rails hoặc bằng cách tìm kiếm nguồn. Bất cứ ai cũng có thể giải thích cho tôi cách thức hoạt động của nó (những tùy chọn nào bạn có thể sử dụng, v.v.) hoặc chỉ cho tôi đến nơi nó thực sự được triển khai để tôi có thể tự mình kiểm tra mã?

Câu trả lời:


128

Cập nhật cho Rails 4.2+

#respond_with::respond_to( phương thức lớp nb ) không còn là một phần của Rails . Họ đã được di chuyển vào đá quý của người trả lời bên thứ ba kể từ Rails 4.2 ( ghi chú phát hành / cam kết ngày 8 tháng 8 năm 2014). Mặc dù người trả lời không được bao gồm trong Rails theo mặc định, nhưng đó là sự phụ thuộc của Devise và do đó có sẵn trong nhiều ứng dụng Rails.

Các #respond_to phương pháp dụ, tuy nhiên, là vẫn còn là một phần của Rails (5.2rc1 như các văn bản này).

Tài liệu API Rails chính thức để ActionController::MimeRespondsgiải thích cách #respond_tohoạt động. Các nhận xét tài liệu hướng dẫn Rails ban đầu cho #respond_with::respond_tovẫn có thể được tìm thấy trong mã nguồn đá quý của người trả lời .


Câu trả lời gốc

Mã cho người trả lời được dựa trên một lớp và một mô-đun. MimeR tương ứng được bao gồm trong ActionControll :: Base , lớp ApplicationControllerkế thừa của bạn . Sau đó, có ActionControll :: responder cung cấp hành vi mặc định khi sử dụng respons_with.


Theo mặc định, các đường ray hành vi duy nhất cung cấp trong phản hồi là một nỗ lực ngầm định để hiển thị một mẫu có tên khớp với hành động. Bất cứ điều gì ngoài yêu cầu nhiều hướng dẫn hơn trong hành động hoặc một cuộc gọi phản hồi tùy chỉnh với một khối để xử lý nhiều phản hồi định dạng.

Vì hầu hết các bộ điều khiển sử dụng một mô hình tùy biến khá phổ biến, người trả lời cung cấp thêm một mức độ trừu tượng bằng cách đưa ra nhiều hành vi mặc định hơn. Đọc các hành động gọi to_xml / to_json cho các định dạng cụ thể và các hành động của trình biến đổi cung cấp tương tự cũng như chuyển hướng cho các hành động biến đổi thành công.


Có một vài cơ hội để tùy chỉnh cách người trả lời hành xử, từ các tinh chỉnh tinh vi để hoàn toàn ghi đè hoặc mở rộng hành vi.

Cấp lớp: respond_to

Ở đây bạn chỉ định các định dạng mà Phản hồi sẽ xử lý. Các định dạng có thể được tùy chỉnh theo hành động mà họ sẽ áp dụng. Mỗi định dạng có thể được chỉ định với các cuộc gọi riêng biệt, cho phép tùy chỉnh hoàn toàn các hành động cho từng định dạng.

# 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]

Cấp lớp: responder

Đây là một thuộc tính lớp giữ phản hồi. Đây có thể là bất cứ điều gì đáp ứng cuộc gọi, có nghĩa là bạn có thể sử dụng một Proc / lambda hoặc một lớp đáp ứng cuộc gọi. Một cách khác là trộn một hoặc một mô-đun vào bộ phản hồi hiện có để làm quá tải các phương thức hiện có, làm tăng hành vi mặc định.

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

Mặc dù có thể có một số trường hợp sử dụng cạnh thú vị, nhiều khả năng việc mở rộng hoặc trộn các mô-đun vào bộ phản hồi mặc định sẽ là các mẫu phổ biến hơn. Trong mọi trường hợp, các tùy chọn có liên quan là tài nguyên và tùy chọn, vì chúng được truyền từ từ answer_with.

Cấp độ sơ thẩm: respond_with

Các tùy chọn ở đây là những tùy chọn sẽ được chuyển qua để kết xuất hoặc redirect_to trong bộ điều khiển của bạn, nhưng chúng chỉ được đưa vào cho các kịch bản thành công. Đối với các hành động GET, đây sẽ là các lệnh gọi kết xuất, đối với các hành động khác, đây sẽ là các tùy chọn để chuyển hướng. Có lẽ hữu ích nhất trong số này là :locationtùy chọn, có thể được sử dụng để ghi đè đường dẫn chuyển hướng đó trong trường hợp các đối số cho answer_with không đủ để xây dựng URL đúng.

# 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'))

Thay thế, đá quý của người trả lời không chỉ cung cấp một số mô-đun để ghi đè một số hành vi mặc định. Nó ghi đè lên bộ trả lời mặc định bằng một lớp ẩn danh mở rộng bộ trả lời mặc định và cung cấp một phương thức cấp lớp để trộn các mô-đun tùy chỉnh vào lớp này. Hữu ích nhất ở đây là bộ phản hồi flash, cung cấp một bộ đèn flash mặc định, tùy chỉnh ủy quyền cho hệ thống I18n, config/locales/en.ymltheo mặc định.

Một số ví dụ về người trả lời tùy chỉnh mà tôi đã sử dụng trong các dự án trước đó bao gồm bộ phản hồi tự động trang trí tài nguyên của tôi và cung cấp một bộ tiêu đề trang mặc định với giao diện để dễ dàng tùy chỉnh hoặc ghi đè tiêu đề trang.


1
Tôi nghĩ bạn có nghĩa là (trong cơ thể lớp) self.responder =như responder =sẽ chỉ định cho một người địa phương
Horseyguy

Cảm ơn bạn! Sự tồn tại của locationtùy chọn là thông tin tôi cần!
JellicleCat

1
Giải thích đó có còn phù hợp với Rails 4/5 không? Tôi đã nghe nói rằng respond_withsẽ bị phản đối, nhưng tôi không thể tìm hiểu tại sao.
Arnlen

1
@Arnlen, respons_with đã được trích xuất dưới dạng một viên ngọc riêng biệt ' người phản hồi '
Nick Roz

Lưu ý rằng để đèn flash config/locales/en.ymlhoạt động, bạn cần responders :flashở đầu bộ điều khiển.
bjnord
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.