我正在Rails 3.1中构建一个简单的json API。我创建了一个具有两个功能的控制器:
class Api::DogsController < ActionController::Base
respond_to :json, :xml
def index
respond_with({:msg => "success"})
end
def create
respond_with({:msg => "success"})
end
end
在routes.rb中我有
namespace :api do
resources :dogs
end
当我向http://localhost:3000/api/dogs发出get请求时,我从上面得到了正确的json。当我对同一个网址发帖时,我得到一个rails例外:
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'
但是如果我将创建代码更改为
def create
respond_with do |format|
format.json { render :json => {:msg => "success"}}
end
end
它返回json就好了。
有人能解释一下这里发生了什么吗?
答案 0 :(得分:38)
在自己遇到这个问题并克服它之后,我相信我能提供答案。
当你简单地说:
def create
respond_with({:msg => "success"})
end
rails试图做的是“猜测”新创建的资源可用的URL,并将其放在HTTP location header中。对于哈希对象,这个猜测失败了(它推导出的位置是nil,这会导致你看到的错误信息)。
要解决此问题,您需要执行以下操作:
def create
respond_with({:msg => "success"}, :location => SOME_LOCATION)
end
假设您知道新资源的位置。您甚至可以将“nil”指定为“SOME_LOCATION”,这将有效(有点荒谬)。
答案 1 :(得分:1)
我自己遇到了这个问题。
正如Aubergine所说,它与http位置标题有关。
实际上,rails似乎默认使用show route
来构建此位置。
如果你没有show action
,这在API中很奇怪,但可能发生(我认为)`,那么你必须自己设置一个位置。我不知道在这种情况下标准是什么。
如果碰巧你需要一个show route,那么就编码吧,一切都应该可以正常工作。
干杯。
答案 2 :(得分:0)
我发现了 errors = {:error =&gt; @ device.errors.full_messages} respond_with(errors,:status =&gt;:bad_request,:location =&gt; nil) 作品。 :当需要使用时,位置是必需的并将其设置为nil有帮助: expect(last_response.status).not_to eql 201 expect(last_response.location).to be_nil
我遇到的问题是我没有返回错误哈希,只返回状态。添加错误哈希并自己设置位置解决了它。