Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Rails, why am I getting a "204 - No Content" response for my update/PATCH/PUT, using Active Model Serializers?

This code is for a UserList (a user can create a User To-Do List). This particular resource does not hold the list items, but just the title of the list, and the type of list.

class Api::V1::UserListsController < ApplicationController
    respond_to :json
    skip_before_filter :verify_authenticity_token

    def index
        if authenticate_user
            user_lists = @current_user.user_lists
            if user_lists
                respond_with user_lists, each_serializer: Api::V1::UserListSerializer
            else
                render json: { error: "Could not find user's lists."}, status: :not_found
            end 
        else
            render json: { error: "User is not signed in." }, status: :unauthorized
        end     
    end         

    def show
        if authenticate_user
            user_lists = @current_user.user_lists
            user_list = user_lists.find_by_id(params[:id])
            if user_list
                respond_with user_list, serializer: Api::V1::UserListSerializer
            else
                render json: { error: "Could not find user's list."}, status: :not_found
            end 
        else
            render json: { error: "User is not signed in." }, status: :unauthorized
        end     
    end     

    def create
        if authenticate_user
            user_list = @current_user.user_lists.new(user_list_params)
            if (user_list.save!)
                respond_with :api, :v1, @current_user, user_list, serializer: Api::V1::UserListSerializer
            else
                render json: { error: "Could not create new User List."}, status: :unprocessable_entity
            end         
        else
            render json: { error: "User is not signed in." }, status: :unauthorized
        end
    end

    def update
        if authenticate_user
            user_list = @current_user.user_lists.find_by_id(params[:id])

            if (user_list.update_attributes(user_list_update_params))
                respond_with :api, :v1, @current_user, user_list, serializer: Api::V1::UserListSerializer                                  
                                    #respond_with user_list, serializer: Api::V1::UserListSerializer
            else
                render json: { error: "Could not update User List." }, status: :unprocessable_entity
            end
        end
    end

    private

        def user_list_params
            params.require(:user_list).permit(:user_id, :type_id, :title)
        end

        def user_list_update_params
            params.require(:user_list).permit(:type_id, :title)
        end
end

Now the update works when I PUT/PATCH... but I get a

Completed 204 No Content in 24ms (ActiveRecord: 4.3ms)

It's been about 4+ months since I've done any rails, and back then I was only just beginning to learn it.

1) Does anyone know why I'm not getting anything back? I know it's something to do with my respond_with line of code in update, but I'm not sure exactly what.

2) Can someone clarify to me the difference between the SHOW respond_with and the CREATE respond_with. I recall having an issue grasping this back then, and obviously now.

SHOW

respond_with user_list, serializer: Api::V1::UserListSerializer

CREATE

respond_with :api, :v1, @current_user, user_list, serializer: Api::V1::UserListSerializer

a) Why does create require :api and :v1 first, but show does not?

b) Why does create require the @current_user, but show does not?

Appendix: Here is my Serializer for reference

class Api::V1::UserListSerializer < ActiveModel::Serializer
  attributes :id, :user_id, :type_id, :title
  has_many :items, embed: :ids
end
like image 975
chris P Avatar asked Oct 14 '14 22:10

chris P


2 Answers

I know this is 2 years too late, but after some digging, I found the empty response with the 204 is intentional (as mentioned above). If you use respond_with this will always be the case. A workaround would be to use render instead (example below):

class Api::V1::ItemsController < ApplicationController
  respond_to :json
  ...

  def update
    @item = Item.find(params[:id]
    if @item
      @item.update_attribute(item_params)
      render json: @item
    end
  end
  ...
end
like image 62
Alan Smith Avatar answered Nov 16 '22 15:11

Alan Smith


You're not supposed to get anything back other than the 204. Any intelligent client does not need to receive back the data it just sent you -- it needs only confirmation that the data was persisted.

like image 22
Brandon Avatar answered Nov 16 '22 14:11

Brandon