【问题标题】:Rails 3 form_tag with 'remote: true' goes to controller as HTML (after Balanced Payments callback?)带有'remote:true'的Rails 3 form_tag作为HTML进入控制器(在Balanced Payments回调之后?)
【发布时间】:2014-12-27 00:08:09
【问题描述】:

在我的主要form_for 中,我有一个带有form_tag 的模式,允许用户将新信用卡添加到他们的帐户中。这个form_tag 具有remote: true,因此请求可以作为Ajax 转到CardsController,其中成功呈现一个模板,该模板关闭模式并将新卡信息添加到主窗体上的现有卡列表中。

问题是请求以 HTML 格式发送到控制器。 SO上有很多关于这个的帖子,但没有一个提供适合我的答案。我正在使用 Google Chrome 进行调试,并在“网络”标签中看到:

我不明白 1) 鉴于我已设置 remote: true 或 2) 为什么状态为 302,我认为这是用于重定向,为什么“类型”是“文本/html”。

可能存在的一个问题是 Balanced Payments balanced.js 正在处理此表单以获取 cc 信息并生成 balanced_card_id,然后将一组参数传递给控制器​​。我猜这就是302 的含义,但我不确定因为我继承了这个系统,也不是 100% 确定平衡支付回调是如何工作的。无论如何,我的form_tag 的路径是需要 xhr 请求的控制器。如果我在CardsController#create 操作的顶部使用binding.pry,我会看到:

balanced.js 回调请求的完整 URL 是 ttps://api.balancedpayments.com/jsonp/cards?callback,后跟一长串字符。它的请求方法为GET,状态码为200。响应如下所示:

{"status":201,"header":{"X-Balanced-Guru":"OHM64f3830e606b11e4ab4502a1fe53e539","Content-Type":"application\/json","x-balanced-host":"bapi-live-prod-7nf6hx-10-3-5-34","x-balanced-software-build":"1.8.39","Content-Length":154,"access-control-allow-origin":"*","access-control-allow-headers":"Content-Type","x-balanced-revision":"1.1","access-control-allow-methods":"POST, OPTIONS","X-Midlr-Version":"2","x-newrelic-app-data":"PxQFWFNXCQYTVVhWAwQDVUYdFhE1AwE2QgNWEVlbQFtcCxYxSBVbDQoZVA4IF0pcXAgEEBhSVhQAQhhQEAMCFlVAFEIIFBQCHVUIUQJUB1tdAwBTUVYLCgBSU04XCAFfSBEUAFVWB1oJW15UClsMC1JVWEMdQVUDCEVSPA=="},"body":"{\n  \"cards\": [\n    {\n      \"href\": \"\/cards\/CC34wrO6NsSYBoVyPM6mTtcC\",\n      \"id\": \"CC34wrO6NsSYBoVyPM6mTtcC\",\n      \"links\": {}\n    }\n  ],\n  \"links\": {}\n}"}
);

控制器使用该哈希中的id 将卡与current_user 关联。不知何故,这个响应变成了我的控制器接收到的实际 params 哈希,我可以通过使用 binding.pry 并在控制台中输入 params 来查看。我明白了:

{"utf8"=>"✓",
 "authenticity_token"=>"HW9/OFAdC373D5L7/yzqKMT2Its2uV31ZxlCe/vQtCU=",
 "balanced_card_id"=>"CC34wrO6NsSYBoVyPM6mTtcC",
 "action"=>"create",
 "controller"=>"money/cards"}

所以我仍然不明白为什么对控制器的原始请求是以 HTML 格式接收的。

这是表格:

  = form_tag(money_cards_path, id: 'new-card', remote: true) do
    .modal-header
      %button{ type: "button", class: "close", data: { dismiss: "modal" }}
        %span{ aria: { hidden: "true" }} ×
        %span.sr-only Close
      %h4.modal-title New Credit Card
    .modal-body
      #errors
      %fieldset
        %p Enter your new credit card information below.
        .row
          .col-sm-8
            = render 'money/cards/form_fields'
    .modal-footer
      = submit_tag "Add Credit Card", class: 'btn btn-success', id: 'new-card-submit', autocomplete: "off"
      .pull-right.cancel
        =link_to 'Cancel', '#', data: { dismiss: "modal" }

这里是控制器:

class Money::CardsController < ApplicationController
  before_filter :authenticate_user!

  def create
    @balanced_marketplace = ENV["BALANCED_MARKETPLACE"] #only if it fails and needs to render again

    respond_to do |format|
      if @card = current_user.add_card(params[:balanced_card_id])
        format.html { redirect_to money_root_path, notice: 'Your credit card has been successfully added.' }
        format.js
      else
        format.html { render action: :new, alert: 'Failed to save credit card to your account. Please contact Sweeps for support.' }
        format.js
      end
    end
  end
end

现在我被重定向到money_root_path,因为请求被格式化为 HTML。

【问题讨论】:

  • 我认为您应该在路径中提供格式,如果您希望它是 js 请求,您可能必须添加form_tag(money_cards_path, format: :js, id: 'new-card', remote: true)

标签: javascript jquery ruby-on-rails ajax forms


【解决方案1】:

确保您的 application.js 中有这两行:

//= require vendor/jquery (your jQuery path)
//= require jquery_ujs

并在您的 gemfile 中添加这一行(就在 gem 'rails', '3.x.x' 之后):

gem 'jquery-rails'

之后你应该执行:

run bundle install

并重新启动您的服务器。它对我有用!当我有一个带有 :remote => true 的元素时,它是由 Ajax 发送的。

【讨论】:

    猜你喜欢
    • 2014-06-22
    • 2011-06-18
    • 2013-12-12
    • 2015-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多