如何让我的rails控制器(CREATE)接受/ POST多个JSON记录?

时间:2014-10-02 04:02:24

标签: ruby-on-rails json api rest

我有一个后端Rails JSON API。现在,我只能根据我编写控制器的方式为每个POST创建一条记录。

假设我们有一个用户可以创建待办事项列表的应用程序,在这些列表中他们可以创建项目。

我们的示例的3个模型,User,UserList和UserListItems

用户has_many UserLists

UserLists has_many UserListItems

现在,我正在使用POST更新UserListItems,但我一次只能添加一个项目。 JSON看起来像......

{
  "user_list_item":
  {
    "item_title": "Buy Milk"
  }
}

使用Active Model Serializers,我将返回它创建的记录,它看起来如下......

respond_with :api, :v1, @current_user, user_list, user_list_item, location: nil, serializer: Api::V1::UserListItemSerializer

{
  "user_list_item": {
    "id": 11,
    "user_list_id": 2,
    "item_title": "Buy Milk"
  }
}

这有严重的缺陷。如果用户创建'Grocery待办事项列表'并且我们POST 1 UserList记录......那很好。但随后他们可能会开始填写购物清单并一次添加3件东西。 “买牛奶”,“买鸡蛋”,“获取气体”。我们现在需要对UserItemList进行3次POST,这远非理想。如果他们添加了20件商品怎么办我们的目标应该是添加所有20合1的POST。

我该怎么办?!?

1)有人可以在控制器中向我展示CREATE的完整示例代码,因为我通过查看/执行语法来学习。我希望能够传递......

{
  "user_list_item":
  [
    {
      "item_title": "Buy Milk"
    },
    {
      "item_title": "Buy Eggs"
    },
    {
      "item_title": "Get Gas"
    }
  ]
}

让我的控制器解析,循环并创建它们。 2)我还希望能够通过Active Model Serializers将记录返回给创建者。例如,所有这三个新添加的记录都在一个回归中(尽管我现在只对第一件事感兴趣)。

编辑:添加原始控制器#create code

    if authenticate_user
        user_list = @current_user.user_lists.find_by_id(params[:user_list_id])
        user_list_item = user_list.user_list_items.new(user_list_item_params)

        if (user_list_item.save!)
            respond_with :api, :v1, @current_user, user_list, user_list_item, location: nil, serializer: Api::V1::UserListItemSerializer
        else
            render json: { error: "Could not create new User List Item."}, status: :unprocessable_entity
        end         
    else
        render json: { error: "User is not signed in." }, status: :unauthorized
    end

private

    def user_list_item_params
        params.require(:user_list_item).permit(:user_list_id, :title, :due_date)
    end 

现在,根据@ Arvoreniad的建议,我现在有以下内容......

    if authenticate_user
        @user_list = @current_user.user_lists.find_by_id(params[:user_list_id])
        @error = false

        user_list_item_params[:user_list_item].each do |attribute|
            item = @user_list.user_list_items.new
            item.title = attribute.title
            item.due_date = attribute.due_date
            @error = true unless item.save
        end

        if (error)
            ????????????????
        else
            render json: { error: "Could not create new User List Item(s)."}, status: :unprocessable_entity
        end

private

    def user_list_item_params
        params.require(:user_list_item).permit(:user_list_id, :title, :due_date)
    end 

我的新问题是

1)所有的?是...我之前使用ActiveModelSerializers来显示新添加的记录,我该如何返回显示所有新添加记录的内容?或者这不是典型的API?将某些东西归还为空而仅仅是否成功是否常见?

2) Can-I / Should-我在1个POST中创建了两个东西(UserList和多个UserListItem都在1个POST中)?如果是这样,怎么样?

3)如果不能正常工作,如何回滚所有保存。假设我试图添加10个项目,9个成功但1个失败,我该如何将它们全部卷回来?

1 个答案:

答案 0 :(得分:1)

如果没有您之前的控制器代码,您的问题有点难以回答,但这应该根据您提供的信息为您提供一个起点。编辑:添加了第1点和第3点的代码。 如果要在同一操作中创建UserList,只需发布​​所需数据并从参数创建一个,而不是在数据库中找到它。如果你愿意,我可以帮助你,但它不应该太难。

def create
  @user_list = UserList.find(params[:id) 
  @error = false # Use this to check before rendering if there has been an error.

  params[:user_list_item].each do |attributes|
    item = UserListItem.new
    item.item_title = attributes.item_title
    item.user_list_id = @user_list.id
    @error = true unless item.valid?
    @items << item
  end

  if(@error)
    render json: { error: "Could not create new User List Item(s)."}, status: :unprocessable_entity
  else
    @items.each do |item|
      item.save
    end

    serialized = ActiveModel::ArraySerializer.new(@items, each_serializer: UserListItemSerializer)
    render json: serialized
  end

end