Rails 3: Update responding with empty json

Hi all!

I'm playing with Rails 3, and on one of my controllers I have the
following update method defined:

def update
    @category = @user.categories.find(params[:id])
    @category.update_attributes(params[:ecategory])
    @category.save
    respond_with @category
  end

I'm using Jquery to interact with the controllers, and when I do an
ajax PUT, the update action is correctly executed (the fields are
updated), but the action returns an empty JSON object, which causes
the Jquery ajax function to fall into an error.

I'm I doing something wrong?

Thank you all,
Fabio.

Hi all!

I’m playing with Rails 3, and on one of my controllers I have the

following update method defined:

def update

@category = @user.categories.find(params[:id])

@category.update_attributes(params[:ecategory])

@category.save

respond_with @category

end

Fabio, you should not be calling save within the update

action because ‘update_attributes’ calls save implicitly.

Thus, you should do something like the following:

class CategoriesController < ApplicationController::Base

respond_to :html, :json

def update

@category = @user.categories.find( params[:id] )
      if @category.update_attributes( params[:category] )
     flash[:notice] = 'Category was successfully created.'
    end
   respond_with( @category )
end
end
Good luck,
-Conrad

Thanks Conrad, I have removed the save call from the code, but it
continues to return an empty JSON on success case.
Any more clues?

Thanks Conrad, I have removed the save call from the code, but it

continues to return an empty JSON on success case.

Any more clues?

Fabio, what happens in the Rails 3 console? For example, you can do the

following in the Rails console:

a) get a user

b) retrieve a category from the user’s list of categories

c) convert the result in (b) into json

Next, what does the jQuery code look like?

-Conrad

Hi Conrad,
I have tried Rails console, and while trying to convert to json the
results were the expected.

This is the Jquery code used on my ajax form:

$('#category_form').submit(function() {
    var form = $(this);
    $.ajax({
      url: form.attr('action'),
      type: 'POST',
      data: form.serialize(),
      success: function(data, status, req) {
        reloadCategories();
      },
      error: function(req, status, error) {
        setFormErrors(form, req);
      }
    });
    return false;
  });

This function is used with both create and update forms, but on create
everything goes ok and it falls on the success function, while during
update, the JSON result comes blank, Jquery gets an error while trying
to parse the empty Json object and it falls on the error function.
..

Hi Conrad,

I have tried Rails console, and while trying to convert to json the

results were the expected.

This is the Jquery code used on my ajax form:

$(’#category_form’).submit(function() {

var form = $(this);

$.ajax({

  url: form.attr('action'),

  type: 'POST',

  data: form.serialize(),

  success: function(data, status, req) {

    reloadCategories();

  },

  error: function(req, status, error) {

    setFormErrors(form, req);

  }

});

return false;

});

This function is used with both create and update forms, but on create

everything goes ok and it falls on the success function, while during

update, the JSON result comes blank, Jquery gets an error while trying

to parse the empty Json object and it falls on the error function.

Can you post the view template of the form?

-Conrad

This is it (HAML):

#category-form
  - form_for @category, :remote => true do |f|
    %fieldset
      %legend= t('activerecord.models.category')
      %p
        = f.label :name
        %br
        = f.text_field :name
      %p
        %button{:type => 'submit', :class => 'positive'}=
t('dashboard.save')

The same form is used both for create and update. I use this Jquery
code to change between create and update actions (this is called on
click of the 'new category' button', or on the on click of an existing
category:

  attr = $(this).data('attributes');
  form = categoryForm.find('form');
  form.find('input[name=_method]').remove();

  if(attr.id) {
    action = '/categories/'+attr.id;
    form.append($('<input/>', {type: 'hidden', name: '_method', value:
'put'}));
  } else {
    action = '/expense_categories';
  }

  $.each(attr, function(i, val){
    categoryForm.find('[id$='+i+']').val(val);
  });

  form.attr('action', action);

No ideas?

I am still stuck with this. Does anyone knows if this is the expected
beavior for Rails? Should respond_with on update really return an
empty json object?

Fabio Kreusch wrote:

I am still stuck with this. Does anyone knows if this is the expected
beavior for Rails? Should respond_with on update really return an
empty json object?

I pretty sure the Rails behavior is as intended. Rails basically says
the save was successful by returning a 200 status code.

jQuery however, considers the request successful if it gets a 200 status
code AND some valid json content.

Personally, I like the Rails way better here.

But nonetheless, I'm currently stuck with the same problem.

An ugly (but working!) solution would be to replace your respond_with
with this
render :json => { :ok => true }

Did you find a nicer solution?

Hi all,

I too have same problem.
Problem: I am getting "successfully stored." alert message, but getting
"null" value in suceeding alert message. whether as expected data is
{"id" => "xx"}

the code is as follows
----------------controller code------------------------
@tmp = {}
    @tmp[:id] = "xx"

    respond_with do |format|
      format.html{ render :json => @tmp }
      format.js
    end

-----------------javascript----------------------------
$.ajax({
                    url: image.saveUrl,
                    type: 'POST',
                    data: form.serialize(),
                    error: function(e) {
                        alert("An error occured saving that note.")
                    },
                    success: function(data, status, req) {
                        alert(" successfully stored.");
                        alert(data);
                    },
                    dataType: "json"
                });
            }

Can anyone help me.

Thank u,
Aashish

I found the solution.

use firebug to see response.

Use image as attachment for help