rmcsharry
rmcsharry

Reputation: 5562

Rails 5.1 how to render no content response in format.json

I have looked at at least 10 questions on this and tried everything (eg. like this question), but none of the suggestions work, eg:

This for example:

format.json head :no_content and return

throws this error:

ArgumentError (wrong number of arguments (given 2, expected 1)):

Whilst this:

format.json head and return

throws this error:

ArgumentError (wrong number of arguments (given 0, expected 1..2)):

This is what I currently have in the controller action:

def paid
    @user = User.find_by(id: session['user_id'])
    respond_to do |format|    
      if [email protected]?
        @user.is_paid = true
        @user.payment_reference = payment_params[:reference]
        @user.save
        format.json { render head, status: :no_content } and return
      else
        format.json render json: { message: "failed to record payment" }, status: :unprocessable_entity
      end
    end
  end

This works but in the console throw an error:

No template found for PaymentsController#paid, rendering head :no_content

I don't want to add an empty template to solve this. I want to tell Rails that I want to render head :no_content!

This question shows that in Rails 3.1 the default generated code did this:

format.json { head :no_content }

but that shows the same exact error in the log.

Upvotes: 4

Views: 5995

Answers (1)

rmcsharry
rmcsharry

Reputation: 5562

So, it turns out this action was being called from an ajax request, which is like this (notice no dataType is specified):

    $.ajax({
        type : 'POST',
        beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))},  
        url : '/payments/paid',
        data: JSON.stringify(paymentObject),
        contentType: 'application/json; charset=utf-8',
        success: record_payment_success,
        error: function() {
          console.log('Error recording payment in db');
        }
    });

So if I do this in rails, the error about missing template is gone:

    format.js { head :no_content }

So it's fine with a js response, so if I change the ajax to this:

    $.ajax({
        type : 'POST',
        beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))},  
        url : '/payments/paid',
        data: JSON.stringify(paymentObject),
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        success: record_payment_success,
        error: function() {
          console.log('Error recording payment in db');
        }
    });

then this works in Rails:

    format.json { head :no_content }

I get a 204 No Content response, and there is no error in the log.

Started POST "/payments/paid" for 127.0.0.1 at 2017-07-19 18:05:31 +0200
Processing by PaymentsController#paid as JSON
  Parameters: {"payment"=>{"reference"=>"PAY-76D56139RT7576632LFXYGPA"}}
Completed 204 No Content in 181ms (ActiveRecord: 26.9ms)

Upvotes: 3

Related Questions