ruby-on-rails - 如何通过覆盖诸如 respond_with 之类的方法来干掉 Rails 3 Controller ?

标签 ruby-on-rails jsonp dry ruby-on-rails-3 respond-with

我正在尝试为我的 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/

    相关文章:

    ruby-on-rails - Rails ActionMailer 中的 Net::SMTPAuthenticationError 502 5.5.2

    javascript - 巫术/ capybara : Cannot log in with :js => true

    javascript - 使用jsonp将数据发送到远程服务器

    node.js - 使用 Express.js 时如何在 Angular.js 中自动声明路由

    javascript - 简化复选框链接的 jquery/javascript

    ruby-on-rails - 在 Controller rails 中的 redirect_to 之前检查 url 的状态代码

    ruby-on-rails - Rails 3.1 RC 中 "illegal hardware instruction rails server"错误的任何已知原因?

    php - jsonp、json、jquery、ajax 和 wordpress 刷新页面! :S

    jquery - CORS header 'Access-Control-Allow-Origin' 丢失

    javascript - 如何设置一系列setHeader的DRY