2009-03-03 41 views
18

Tôi đang tìm cách hiển thị chỉ mục của tất cả các bài báo cùng với một bài viết đầy đủ thông qua JSON trong ứng dụng đường ray của tôi, nhưng tôi đang gặp một chút khó khăn trong việc tìm ra cách thực hiện.Ruby on Rails Nâng cao JSON Serialization

Đây là bộ điều khiển của tôi bây giờ:

if params[:id] 
    @article = Article.find(params[:id]) 
else 
    @article = Article.published.not_draft.by_recent.first 
end 

respond_to do |format| 

format.js { render :json => @article.to_json(
:except => [ :created_at, :updated_at, :draft, :id, :publish ], 
:include => { 
    :comments => { 
     :only => [:body] 
    } 
}), 
:callback => params[:callback]} 
end 

Những gì tôi muốn làm trong các phản ứng là thêm một chỉ số của tất cả các bài viết, như vậy:

@index = Article.find(:all, :select => 'id, title') 

Cách duy nhất tôi đã có thể làm điều đó, được đặt cả chỉ mục và bài viết vào một băm hoặc mảng và sau đó đặt nó vào JSON.

@response = { :item => @article, :index => @index } 

Toàn mã với cả hai:

@index = Article.find(:all, :select => 'id, title') 

if params[:id] 
    @article = Article.find(params[:id]) 
else 
    @article = Article.published.not_draft.by_recent.first 
end 

@response = { :item => @article, :index => @index } 

respond_to do |format| 

format.js { render :json => @response.to_json(), :callback => params[:callback]} 

end 

Đây sẽ là tốt, ngoại trừ bây giờ tôi không thể xác định :include hay :except và làm cho nó hiển thị chính xác.

Trả lời

1

Bạn sẽ có thể tổ :include, :except, vv như vậy:

:except => {:item => [ :created_at, :updated_at, :draft, :id, :publish ]}... 

Nếu điều đó không làm việc, làm cho nó một đối tượng (ví dụ một OpenStruct) thay vì một băm.

- Markus

2

Chỉ cần làm rõ mã ở trên hoạt động với: bao gồm và: ngoại trừ. Và bởi các công trình tôi có nghĩa là nó không ném một lỗi. Vấn đề là nó bao gồm các bình luận cho mỗi bài viết trong chỉ mục. Tôi chỉ tìm kiếm để bao gồm các ý kiến ​​cho: mục và không phải bất kỳ bài viết nào được liệt kê trong chỉ mục.

Tôi không thể lồng ghép để làm việc dưới dạng băm hoặc đối tượng OpenStruct.

Làm tổ trên: bao gồm ném lỗi, lồng vào: ngoại trừ không ném lỗi, nhưng không có gì được lọc ra,: created_at, v.v. vẫn hiển thị.

... 

@response = { :item => @article, :index => @index } 

format.js { render :json => @response.to_json(
:except => {:item => [ :created_at, :updated_at, :draft, :id, :publish ]}, 
:include => { :item => { 
     :comments => { 
       :only => [:body] 
     } 
}}), 
:callback => params[:callback]} 
end 
1

to_json có: Phương pháp lựa chọn bao gồm kết quả của bất kỳ phương pháp nào bạn đặt tên, bạn có thể xác định một phương pháp trên mô hình đó mà trả về dữ liệu bổ sung mà bạn muốn trong JSON của bạn.

28

Bạn gợi ý giải pháp trong câu hỏi của mình. Bạn rất có thể muốn xây dựng một băm để hiển thị cho JSON. Cách ưa thích để làm điều này ngay bây giờ là cung cấp cách triển khai cho phương thức as_json. as_json cung cấp một phương tiện chính thức để tùy chỉnh đầu ra to_json bằng cách xây dựng một băm chứa dữ liệu bạn muốn mã hóa.

Điều trị kỹ lưỡng hơn về cách tương tác as_json và to_json có thể được tìm thấy trên Jonathan Julian's weblog.

1

(Vui lòng chấp nhận câu trả lời)

Tôi nghĩ rằng liên kết mà nirvdrum đã đưa ra câu trả lời của bạn. Tôi chỉ trả lời vì không ai đề cập đến encode_json.

Trong trường hợp của bạn, bạn chỉ nên xử lý as_json.Hoặc bằng cách xây dựng một băm (với các cuộc gọi khác nhau đến as_json) và gửi đến render :json => ... (không có cuộc gọi đến to_json) hoặc bằng cách thực hiện đơn giản as_json trên mô hình của bạn và cho phép thực hiện tất cả các công việc. (Nhưng tôi nghi ngờ bạn sẽ cần trước đây.)

Nếu bạn thực sự cần một số js lạ mắt trong phản hồi trả về của bạn thì bạn có thể thực hiện encode_json trong các lớp học của bạn (một lần nữa, không phải to_json). Ví dụ:

class JsEmptyClosure 
    def encode_json(*args) 
    "jQuery[\"noop\"] || function(){}" 
    end 
    def as_json(*args) self end 
end 

Điều này sẽ trả lời to_json với js hợp lệ (nhưng lưu ý nó không thực sự là json).

0

Cảm ơn câu hỏi, tôi có thể tùy chỉnh định dạng json của tôi cho một mô hình với một số liên kết.

làm json: @ posts.to_json (

: trừ => [: created_at,: updated_at,: user_id],

: include => {

: user => {: only => [: email,: phone]},

: location => {: only => [: title,: lat,: lon,: street,: city,: state, : zipcode] },

.210

: Tải lên => {: chỉ => [: image]}

}
)

0

Tôi muốn giới thiệu quá tải phương pháp thuộc tính để trả lại một băm alternat sẽ được tự động sử dụng trong sản lượng to_json .

class Article 
    def attributes 
    { ... } # define your hash that you want to return at the '...' 
    end 
end 

Đối với tôi, điều này có vẻ đơn giản hơn nhiều so với mút xung quanh với to_json trực tiếp.