2011-09-05 18 views
16

Tôi đang xây dựng một API json đơn giản trong Rails 3.1. Tôi tạo ra một bộ điều khiển có hai chức năng:Rails respond_with hành động khác nhau trong chỉ mục và tạo phương thức

class Api::DogsController < ActionController::Base 
    respond_to :json, :xml 
    def index 
    respond_with({:msg => "success"}) 
    end 

    def create 
    respond_with({:msg => "success"}) 
    end 
end 

Trong routes.rb Tôi có

namespace :api do 
    resources :dogs 
end 

Khi tôi thực hiện một yêu cầu get để http://localhost:3000/api/dogs tôi nhận được json đúng từ trên cao. Khi tôi thực hiện một đường bưu điện đến địa chỉ đó, tôi nhận được một đường ray ngoại lệ:

ArgumentError in Api::DogsController#create 
Nil location provided. Can't build URI. 
actionpack (3.1.0) lib/action_dispatch/routing/polymorphic_routes.rb:183:in `build_named_route_call` 
actionpack (3.1.0) lib/action_dispatch/routing/polymorphic_routes.rb:120:in `polymorphic_url' 
actionpack (3.1.0) lib/action_dispatch/routing/url_for.rb:145:in `url_for' 

Nhưng nếu tôi thay đổi mã tạo để

def create 
    respond_with do |format| 
    format.json { render :json => {:msg => "success"}} 
    end 
end 

nó trả về json tốt.

Ai đó có thể giải thích những gì đang xảy ra ở đây?

Trả lời

38

Sau khi tự mình gặp vấn đề này và khắc phục nó, tôi tin rằng tôi có thể cung cấp câu trả lời.

Khi bạn chỉ đơn giản nói:

def create 
    respond_with({:msg => "success"}) 
end 

gì ray cố gắng làm là "đoán" một url rằng tài nguyên mới được tạo ra có sẵn tại, và đặt nó trong HTTP location header. Đó đoán thất bại thảm hại cho một đối tượng băm (vị trí nó suy ra là số không, dẫn đến thông báo lỗi bạn đang thấy).

Để khắc phục vấn đề này, sau đó, bạn sẽ cần phải làm như sau:

def create 
    respond_with({:msg => "success"}, :location => SOME_LOCATION) 
end 

Giả sử bạn biết nơi mà các tài nguyên mới nằm. Bạn thậm chí có thể chỉ định "nil" là "SOME_LOCATION" và điều đó sẽ hoạt động (hơi ngớ ngẩn).

+1

Đặt vị trí thành chuỗi chữ "nil" đã hoạt động: 'respond_with ({: error =>" bad "},: status => 401,: location =>" nil ")' –

+0

@kwbeam Tôi đã nói về một giá trị nil thực tế trong đoạn cuối (tôi nhận ra rằng các dấu ngoặc kép có thể gây hiểu nhầm) – Aubergine

+0

Tôi đã nghĩ rằng bạn có nghĩa là không phải là đối tượng, không phải là chuỗi chữ, nhưng khi tôi thử nó, nó vẫn thất bại. Tuy nhiên, tôi chỉ cần thay đổi nó trở lại để nil (đối tượng, không phải là chuỗi chữ) và nó đang làm việc. Vì vậy, dường như tôi đã thất bại ở đâu đó, nhưng tôi không thể tái tạo lại những gì tôi đã làm sai. Xin lỗi vì sự nhầm lẫn. (Tôi đã cập nhật phiên bản của Rails và nhiều viên đá quý trong thời gian tạm thời, vì vậy có lẽ đã có một lỗi đã được sửa ... nhưng tôi không chắc chắn) –

1

Tôi đã gặp sự cố.

Nó giống như Aubergine nói, có liên quan đến tiêu đề vị trí http.

Thực tế, đường ray dường như xây dựng vị trí này bằng cách sử dụng theo mặc định là show route.

Nếu bạn không có số show action, thì điều gì lạ trong API, nhưng có thể xảy ra (tôi nghĩ) `, thì bạn phải tự đặt vị trí. Tôi không biết tiêu chuẩn trong trường hợp này là gì.

Nếu điều đó xảy ra, bạn cần một tuyến đường hiển thị, sau đó mã hóa nó và mọi thứ sẽ hoạt động tốt.

Chúc mừng.

0

Tôi đã phát hiện ra rằng errors = {: lỗi => @} device.errors.full_messages respond_with (lỗi,: status =>: bad_request,: vị trí => nil) công trình. Các: vị trí được yêu cầu và thiết lập nó để nil giúp khi sử dụng với spec: mong đợi (last_response.status) .not_to eql 201 mong đợi (last_response.location) .to be_nil

Vấn đề tôi đang gặp là tôi đã không trả về lỗi băm, chỉ là trạng thái. Thêm hash lỗi và thiết lập vị trí bản thân mình đã giải quyết nó.

Các vấn đề liên quan