我正在尝试为我的 Rails 3 应用程序创建 JSONP API。现在在我的 Controller 中,我有很多遵循这种模式的操作:
# This is from my users_controller.rb, as an example
def index
@users = User.all
respond_with(@users, :callback => params[:callback])
end
虽然这是按原样工作的,但我想通过不必重复
:callback => params[:callback]
来干掉它。在每个行动的呼吁respond_with
.我怎样才能做到这一点?更新:我意识到我上面的代码很难看的一件事是
:callback => params[:callback]
选项将传递给任何响应格式,而不仅仅是 JSON。下面的代码可能更正确:def index
@users = User.all
respond_with(@users) do |format|
format.json { render :json => @users, :callback => params[:callback]}
end
end
我考虑过几种方法来解决这个问题,但我不知道如何使它们起作用:
render
(可能在应用程序 Controller 中),以便它接受 :jsonp
自动包含 :callback => params[:callback]
的选项范围。这样我可以将上面的代码更改为以下代码,它会更短一些:def index
@users = User.all
respond_with(@users) do |format|
format.json { render :jsonp => @users}
end
end
to_json
的响应程序为了解决我的问题。这样我就可以忽略该 block ,只需调用 respond_with(@users, :responder => 'MyResponder')
解决问题。或者我可以使用 plataformatec's responders gem 将此代码包含在应用程序响应程序中。这样respond_with(@users)
本身就足够了。 最佳答案
请注意,从技术上讲,使用回调参数呈现 JSON 是不正确的,因为您得到的是 JavaScript 响应(对 JSON-P 回调的函数调用)而不是 JSON 结果。
所以如果你有
render :json => my_object, :callback => params[:callback]
以及对
/users?callback=func
的请求进来,Rails 会回答func({…})
内容类型为
application/json
,这是不正确的,因为上面的响应显然不是 JSON 而是 JavaScript。我使用的解决方案是
def respond_with_json(item)
respond_with do |format|
format.json { render :json => item }
format.js { render :json => item, :callback => params[:callback] }
end
end
在有或没有回调的情况下正确响应。将其应用于上述解决方案,我们得到:
def custom_respond_with(*resources, &block)
options = resources.extract_options!
if params[:callback]
old_block = block
block = lambda do |format|
old_block.call(format) if block_given?
format.js { render :json => resources[0], :callback => params[:callback] }
end
end
respond_with(*(resources << options), &block)
end
另请注意对
resources[0]
的更正, 否则你最终会包装 resources
由于 splat 运算符,在一个额外的数组中。
关于ruby-on-rails - 如何通过覆盖诸如 respond_with 之类的方法来干掉 Rails 3 Controller ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4467532/