2

In my main form_for I have a modal with a form_tag that allows a user to add a new credit card to their account. This form_tag has remote: true so that the request can go to the CardsController as Ajax, where success renders a template that closes the modal and adds the new card info to the existing cards list on the main form.

The problem is that the request is going to the controller as HTML. There are a number of posts about this here on SO, but none have provided an answer that works for me. I'm using Google Chrome to debug, and in the 'Network' tab I see this:

Chrome 'Network'

I don't understand 1) why the 'type' is 'text/html' given that I have set remote: true or 2) why the status is 302, which I think is for a redirect.

One issue that may be at play is that this form is being acted upon by the Balanced Payments balanced.js to take cc info and generate a balanced_card_id that is then passed in a set of params to the controller. I'm guessing this is what the 302 is about but I'm not sure as I inherited this system and am not 100% sure how the Balanced Payment callback is working. At any rate, the path for my form_tag is the controller that expects an xhr request. If I use binding.pry at the top of the CardsController#create action, I see this:

Network 2

The full URL for the balanced.js callback request is ttps://api.balancedpayments.com/jsonp/cards?callback followed by a long string of characters. It has a request method of GET and a status code of 200. The response looks like this:

{"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}"}
);

It is the id in that hash that the controller uses to associate the card with current_user. Somehow this response becomes the actual params hash that my controller receives, which I can see by using binding.pry and typing params in the console. I get this:

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

So I still don't understand why the original request to the controller is being received as HTML.

Here is the form:

  = 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" }

And here is the controller:

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

Right now I'm being redirected to the money_root_path because of the request being formatted as HTML.

sixty4bit
  • 7,422
  • 7
  • 33
  • 57
  • I think you should provide the format in your path, if you want it to be a js request, you will probably have to add `form_tag(money_cards_path, format: :js, id: 'new-card', remote: true)` – Ruby Racer Oct 30 '14 at 21:19
  • see http://stackoverflow.com/a/16997551/1197775 – sites Oct 31 '14 at 17:38

1 Answers1

0

Be sure you have these two line on your application.js:

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

and in your gemfile add this line (just after gem 'rails', '3.x.x'):

gem 'jquery-rails'

after that you should execute:

run bundle install

and restart your server. It worked for me! when I have an element with :remote => true, it is sent by Ajax.

Leo
  • 712
  • 8
  • 10