Trong Rails, làm thế nào để bạn kết xuất JSON bằng cách sử dụng một khung nhìn?


125

Giả sử bạn đang ở trong trình điều khiển người dùng của mình và bạn muốn nhận được phản hồi json cho yêu cầu hiển thị, thật tuyệt nếu bạn có thể tạo tệp trong chế độ xem / người dùng / thư mục của mình, được đặt tên là show.json và sau khi người dùng của bạn # hiển thị hành động được hoàn thành, nó làm cho các tập tin.

Hiện tại bạn cần phải làm một cái gì đó dọc theo dòng:

def show
  @user = User.find( params[:id] )
  respond_to do |format|
    format.html
    format.json{
      render :json => @user.to_json
    }
  end
end

Nhưng thật tuyệt nếu bạn có thể tạo một tệp show.json tự động được hiển thị như vậy:

def show
  @user = User.find( params[:id] )
  respond_to do |format|
    format.html
    format.json
  end
end

Điều này sẽ giúp tôi tiết kiệm được rất nhiều đau buồn và sẽ gột rửa cảm giác bẩn thỉu khủng khiếp mà tôi có được khi đưa json vào bộ điều khiển


Nhìn vào bài đăng này bây giờ, có vẻ như điều này sẽ không giúp tôi tiết kiệm nhiều, nhưng tôi có những trường hợp phức tạp hơn, hãy tin tôi khi tôi nói điều này khiến tôi đau đầu
Matthew

1
Trong Rails 3, bạn chỉ có thể gọi format.jsonvới một show.json.erbtệp. Xem câu trả lời của tôi.
James Lim

Câu trả lời:


64

Bạn sẽ có thể làm một cái gì đó như thế này trong respond_tokhối của bạn :

respond_to do |format|
    format.json 
    render :partial => "users/show.json"
end

Nó sẽ làm cho mẫu trong app/views/users/_show.json.erb.


5
Điều này là tốt, nhưng bạn sẽ nhanh chóng thấy erb là một cách đau đớn để tạo ra json. Kiểm tra câu trả lời của tôi cho một số lựa chọn thay thế.
tybro0103

1
Có cách nào để làm điều đó mà không sử dụng một phần?
Wylliam Judd

55

Hãy thử thêm một khung nhìn users/show.json.erbĐiều này sẽ được hiển thị khi bạn đưa ra yêu cầu cho định dạng JSON và bạn cũng nhận được lợi ích bổ sung của nó được hiển thị bởi erb, vì vậy tệp của bạn có thể trông giống như thế này

{
    "first_name": "<%= @user.first_name.to_json %>",
    "last_name": "<%= @user.last_name.to_json %>"
}

9
Bạn có thể muốn sử dụng @user.first_name.to_jsonthay vì escape_javascript. Có một số khác biệt tinh tế giữa những gì JS cho phép và JSON hoàn toàn là gì . (Và những khác biệt đó đang trở nên quan trọng khi các trình duyệt triển khai các trình phân tích cú pháp JSON của riêng họ.)
James A. Rosen

1
Có lẽ bạn nên thay đổi các trích dẫn đơn thành dấu ngoặc kép, vì JSON (không giống như JS) chỉ chấp nhận chuỗi trích dẫn kép.
Abe Voelker

1
Điều này là tốt, nhưng bạn sẽ nhanh chóng thấy erb là một cách đau đớn để tạo ra json. Kiểm tra câu trả lời của tôi cho một số lựa chọn thay thế.
tybro0103

Tôi biết đây là một câu trả lời cũ, nhưng nó hoàn toàn sai. to_json sẽ trả về một chuỗi json được định dạng "", do đó, json kết quả sẽ không bao giờ hợp lệ với dấu ngoặc kép ("" value ""). Ngoài ra, nếu tên người dùng là nil, json kết quả sẽ có chuỗi "null" làm giá trị. Ngoài ra <% = sử dụng thoát html sẽ thu thập các ký tự html trong dữ liệu đầu vào.
d4n3

Tôi nghĩ bạn cũng cần xóa các trích dẫn xung quanh <%= xyz.to_json %>nếu không bạn còn lại với các trích dẫn thêm.
akostadinov

32

Như những người khác đã đề cập, bạn cần có chế độ xem người dùng / show.json, nhưng có các tùy chọn để xem xét cho ngôn ngữ tạo khuôn mẫu ...

ERB

Sáng tạo. Tuyệt vời cho HTML, nhưng bạn sẽ nhanh chóng thấy nó thật tệ cho JSON.

RABL

Giải pháp tốt. Phải thêm một phụ thuộc và tìm hiểu DSL của nó.

Trình tạo JSON

Tương tự như RABL: Giải pháp tốt. Phải thêm một phụ thuộc và tìm hiểu DSL của nó.

Hồng ngọc

Ruby thật tuyệt vời khi tạo JSON và không có gì mới để học khi bạn có thể gọi to_jsonHash hoặc đối tượng AR. Chỉ cần đăng ký tiện ích mở rộng .rb cho các mẫu (trong trình khởi tạo):

ActionView::Template.register_template_handler(:rb, :source.to_proc)

Sau đó tạo chế độ xem người dùng / show.json.rb:

@user.to_json

Để biết thêm thông tin về cách tiếp cận này, hãy xem http://railscasts.com/episodes/379-template-handlers


7
Lưu ý rằng trong rails 4, trình xử lý mẫu .ruby được đăng ký theo mặc định github.com/rails/rails/commit/de1060f4e02925c12004f2 để bạn có thể bỏ qua việc đăng ký .rb và đặt tên cho người dùng tệp của bạn / show.json.ruby.
Tim Diggins

1
Ngoài ra, để cập nhật thêm, json_builder đã được github.com/rails/jbuilder cung cấp .
Tim Diggins

27

RABL có lẽ là giải pháp tốt nhất cho vấn đề này mà tôi đã thấy nếu bạn đang tìm kiếm một giải pháp thay thế sạch hơn cho cú pháp ERb. json_builder và argonaut, là những giải pháp khác, cả hai đều có vẻ hơi lỗi thời và sẽ không hoạt động với Rails 3.1 mà không có một số bản vá.

RABL có sẵn thông qua một viên ngọc hoặc kiểm tra kho GitHub; ví dụ tốt

https://github.com/nesquena/rabl


21

Chỉ cần cập nhật câu trả lời này vì lợi ích của những người khác cuối cùng trên trang này.

Trong Rails 3, bạn chỉ cần tạo một tệp tại views/users/show.json.erb. Đối @usertượng sẽ có sẵn để xem (giống như đối với html.) Bạn thậm chí không cần to_jsonnữa.

Tóm lại, nó chỉ là

# users contoller
def show
  @user = User.find( params[:id] )
  respond_to do |format|
    format.html
    format.json
  end
end

/* views/users/show.json.erb */
{
    "name" : "<%= @user.name %>"
}

1
Tôi đã trả lời điều này 1,5 năm trước. Ngày nay tôi chỉ sử dụng answer_with bất cứ khi nào tôi cần JSON, vd respond_with @user, only: [:name]. Tham khảo hướng dẫn này để biết thêm thông tin.
James Lim

1
Chỉ cần thêm vào câu trả lời này, điều này thực sự nguy hiểm vì hai lý do: nó cho phép tiêm từ dữ liệu người dùng vì nó không thoát khỏi dòng mới và dấu gạch chéo ngược, và <% = html thoát dữ liệu, ví dụ Sean O'Connor sẽ có tên của anh ấy đọc sai cho Sean O & apos; Connor.
d4n3

10

Chỉ cần thêm show.json.erbtập tin với nội dung

<%= @user.to_json %>

Đôi khi nó hữu ích khi bạn cần một số phương thức trợ giúp bổ sung không có sẵn trong bộ điều khiển, tức là image_path(@user.avatar)hoặc một cái gì đó để tạo các thuộc tính bổ sung trong JSON:

<%= @user.attributes.merge(:avatar => image_path(@user.avatar)).to_json %>

8
Nó sẽ cần phải <%= raw(@user.to_json) %>tránh HTML thoát. Những gì tôi làm là tôi dựa vào to_json miễn là nó mang lại cho tôi những gì tôi muốn, nhưng khi tôi muốn làm một cái gì đó khác, tôi tạo mẫu cho nó với những gì thường là a { :blah => @user.the_blah }.to_json.
clacke


0

Tôi mới biết về RoR đây là những gì tôi tìm ra. bạn có thể trực tiếp kết xuất một định dạng json

def YOUR_METHOD_HERE
  users = User.all
  render json: {allUsers: users} # ! rendering all users
END
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.