我有一个后端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个失败,我该如何将它们全部卷回来?
答案 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