在Rails中,为什么我会得到一个" 204 - No Content"响应我的更新/ PATCH / PUT,使用Active Model Serializers?

时间:2014-10-14 22:31:00

标签: ruby-on-rails rest put active-model-serializers

此代码用于UserList(用户可以创建用户待办事项列表)。此特定资源不包含列表项,而只包含列表标题和列表类型。

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

现在,当我PUT / PATCH时更新正常...但我得到了

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

自从我完成任何操作以来已经有4个多月了,那时我才开始学习它。

1)有谁知道为什么我没有得到任何回报?我知道这与我的respond_with更新代码行有关,但我不确定究竟是什么。

2)有人可以向我澄清SHOW respond_with和CREATE respond_with之间的区别。我记得当时有一个问题正在抓住这个问题,显然现在。

SHOW

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

CREATE

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

a)为什么创建需要:api和:v1首先,但是show不是?

b)为什么create需要@current_user,但是show不需要?

附录:这是我的序列化工具供参考

class Api::V1::UserListSerializer < ActiveModel::Serializer
  attributes :id, :user_id, :type_id, :title
  has_many :items, embed: :ids
end

4 个答案:

答案 0 :(得分:2)

除了204之外,您不应该得到任何回报。任何智能客户端都不需要接收刚发送给您的数据 - 它只需要确认数据是否存在。

答案 1 :(得分:2)

我知道这已经太晚了2年,但经过一番挖掘,我发现204的空洞反应是故意的(如上所述)。如果您使用respond_with,情况总是如此。解决方法是使用render代替(例如下面的代码):

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

答案 2 :(得分:0)

不要错误地将您的班级Api::V1::UserListSerializer作为键/值对(哈希表单)传递。您将收到错误消息,包括类或所需模块。它应该是这样的:

serialize :some_array, Api::V1::UserListSerializer

或者,也许更清楚的是:

serialize(:some_array, Api::V1::UserListSerializer)

您错过了一个参数,而您正在渲染没有内容的对象类:204 - No Content 这似乎是显而易见的,但习惯于将事物作为键/值对传递。

一个改进:

before_action :authenticate_user, only: [:create, :show, :update, ...]

https://apidock.com/rails/ActiveRecord/Base/serialize/class

答案 3 :(得分:-1)

def update
  @item = Item.find(params[:id])
  respond_with(:api, :v1, @item) do |format|
    if @item.update(item_params)
      format.json { render json: @item}
    else
      format.json { render json: {error: @item.errors.full_messages}}
    end
  end
end