RailsAPI应用程序使用来自控制器的post请求一次创建不同模型的多个嵌套记录

e7arh2l6  于 2021-09-29  发布在  Java
关注(0)|答案(1)|浏览(431)

我正在开发一个api RubyonRails6.1应用程序,所以我所有的响应都是json。我正在尝试创建一个3级嵌套记录,这意味着我要创建一个包含多天记录的计划记录,该记录每天包含多顿饭。
plan.rb

  1. class Plan < ApplicationRecord
  2. has_many :days
  3. accepts_nested_attributes_for :days
  4. end

day.rb

  1. class Day < ApplicationRecord
  2. has_many :meals
  3. belongs_to :plan
  4. accepts_nested_attributes_for :meals
  5. end

膳食.rb

  1. class Meal < ApplicationRecord
  2. belongs_to :plan
  3. belongs_to :day
  4. end

这是plans_controller.rb中的方法

  1. # POST /create_custon_plan
  2. def create_custon_plan
  3. @plan = Plan.new(plan_params)
  4. @days = @plan.days
  5. @meals = Meal.where("plan_id = ? ", @plan.id)
  6. if @plan.save
  7. @days.each do |day|
  8. day = Day.find_or_create_by!(name: params[:number], plan_id: @plan.id) if params[:number].present?
  9. if day.save
  10. @meals.each do |meal|
  11. meal = Meal.find_or_create_by!(name: params[:name], plan_id: @plan.id, day_id: day.id) if params[:name].present?
  12. if meal.save
  13. render json: {
  14. messages: "meals was successfully created.",
  15. is_success: true,
  16. status: :created,
  17. data: { meal: meal },
  18. }
  19. else
  20. render json: meal.errors, status: :unprocessable_entity
  21. end
  22. end
  23. render json: {
  24. messages: "days was successfully created.",
  25. is_success: true,
  26. status: :created,
  27. data: { day: day },
  28. }
  29. else
  30. render json: day.errors, status: :unprocessable_entity
  31. end
  32. end
  33. render json: {
  34. messages: "Plan was successfully created.",
  35. is_success: true,
  36. status: :created,
  37. data: { plan: @plan, days: @days, meals: @meals },
  38. }
  39. else
  40. render json: @plan.errors, status: :unprocessable_entity
  41. end
  42. end

这是我的请求机构http://localhost:3000/api/create_custon_plan

  1. {
  2. "name": "Test Plan",
  3. "monthly_price": 0,
  4. "image_url": null,
  5. "days": [
  6. {
  7. "number": 1,
  8. "plan_id": 4,
  9. "meals": [
  10. {
  11. "id": 269,
  12. "name": "Kale Salad",
  13. "calories": null,
  14. "protein": null,
  15. "fat": null,
  16. "carbohydrates": null,
  17. "plan_id": 4,
  18. "image_url": null,
  19. "categorie": "snack-1"
  20. },
  21. {
  22. "id": 270,
  23. "name": "Fit Burger",
  24. "calories": null,
  25. "protein": null,
  26. "fat": null,
  27. "carbohydrates": null,
  28. "plan_id": 4,
  29. "image_url": null,
  30. "categorie": "meal-1"
  31. },
  32. {
  33. "id": 271,
  34. "name": "Vegan Rataouille",
  35. "calories": null,
  36. "protein": null,
  37. "fat": null,
  38. "carbohydrates": null,
  39. "plan_id": 4,
  40. "image_url": null,
  41. "categorie": "snack-2"
  42. },
  43. {
  44. "id": 272,
  45. "name": "Chicken BBQ",
  46. "calories": null,
  47. "protein": null,
  48. "fat": null,
  49. "carbohydrates": null,
  50. "plan_id": 4,
  51. "image_url": null,
  52. "categorie": "meal-3"
  53. }
  54. ]
  55. },
  56. {
  57. "number": 2,
  58. "plan_id": 4,
  59. "meals":
  60. [
  61. {
  62. "id": 273,
  63. "name": "Woldrof Salad",
  64. "calories": null,
  65. "protein": null,
  66. "fat": null,
  67. "carbohydrates": null,
  68. "plan_id": 4,
  69. "image_url": null,
  70. "categorie": "snack-1"
  71. },
  72. {
  73. "id": 274,
  74. "name": "Baked Beef",
  75. "calories": null,
  76. "protein": null,
  77. "fat": null,
  78. "carbohydrates": null,
  79. "plan_id": 4,
  80. "image_url": null,
  81. "categorie": "meal-1"
  82. }
  83. ]
  84. }
  85. ]
  86. }

我们希望创建1个计划记录、多天记录和多个用餐记录,但在终端日志之后,只创建了计划记录,其他模型甚至没有出现在那里,就像代码行不存在一样。这是终端日志

  1. Started POST "/api/create_custon_plan" for ::1 at 2021-07-23 15:43:08 +0100
  2. (0.9ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
  3. Processing by PlansController#create_custon_plan as */*
  4. Parameters: {"name"=>"Test Plan", "monthly_price"=>0, "image_url"=>nil, "days"=>[{"number"=>1, "plan_id"=>4, "meals"=>[{"id"=>269, "name"=>"Kale Salad", "calories"=>nil, "protein"=>nil, "fat"=>nil, "carbohydrates"=>nil, "plan_id"=>4, "image_url"=>nil, "categorie"=>"snack-1"}, {"id"=>270, "name"=>"Fit Burger", "calories"=>nil, "protein"=>nil, "fat"=>nil, "carbohydrates"=>nil, "plan_id"=>4, "image_url"=>nil, "categorie"=>"meal-1"}, {"id"=>271, "name"=>"Vegan Rataouille", "calories"=>nil, "protein"=>nil, "fat"=>nil, "carbohydrates"=>nil, "plan_id"=>4, "image_url"=>nil, "categorie"=>"snack-2"}, {"id"=>272, "name"=>"Chicken BBQ", "calories"=>nil, "protein"=>nil, "fat"=>nil, "carbohydrates"=>nil, "plan_id"=>4, "image_url"=>nil, "categorie"=>"meal-3"}]}, {"number"=>2, "plan_id"=>4, "meals"=>[{"id"=>273, "name"=>"Woldrof Salad", "calories"=>nil, "protein"=>nil, "fat"=>nil, "carbohydrates"=>nil, "plan_id"=>4, "image_url"=>nil, "categorie"=>"snack-1"}, {"id"=>274, "name"=>"Baked Beef", "calories"=>nil, "protein"=>nil, "fat"=>nil, "carbohydrates"=>nil, "plan_id"=>4, "image_url"=>nil, "categorie"=>"meal-1"}]}], "plan"=>{"name"=>"Test Plan", "monthly_price"=>0}}
  5. Can't verify CSRF token authenticity.
  6. TRANSACTION (0.3ms) BEGIN
  7. ↳ app/models/plan.rb:13:in `acceptable_image'
  8. Plan Create (1.0ms) INSERT INTO "plans" ("name", "monthly_price", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["name", "Test Plan"], ["monthly_price", 0], ["created_at", "2021-07-23 14:43:08.845314"], ["updated_at", "2021-07-23 14:43:08.845314"]]
  9. app/controllers/plans_controller.rb:42:in `create_custon_plan'
  10. TRANSACTION (1.0ms) COMMIT
  11. ↳ app/controllers/plans_controller.rb:42:in `create_custon_plan'
  12. Day Load (1.7ms) SELECT "days".* FROM "days" WHERE "days"."plan_id" = $1 [["plan_id", 34]]
  13. ↳ app/controllers/plans_controller.rb:43:in `create_custon_plan'
  14. [active_model_serializers] Meal Load (2.9ms) SELECT "meals".* FROM "meals" WHERE (plan_id = NULL )
  15. [active_model_serializers] app/controllers/plans_controller.rb:69:in `create_custon_plan'
  16. [active_model_serializers] Rendered ActiveModel::Serializer::Null with Hash (5.92ms)
  17. Completed 200 OK in 49ms (Views: 5.3ms | ActiveRecord: 13.8ms | Allocations: 14452)

最后是请求的返回体

  1. {
  2. "messages": "Plan was successfully created.",
  3. "is_success": true,
  4. "status": "created",
  5. "data": {
  6. "plan": {
  7. "id": 34,
  8. "name": "Test Plan",
  9. "monthly_price": 0,
  10. "created_at": "2021-07-23T14:43:08.845Z",
  11. "updated_at": "2021-07-23T14:43:08.845Z",
  12. "is_custom": null
  13. },
  14. "days": [],
  15. "meals": []
  16. }
  17. }

很抱歉,我说了这么长时间,但我想尽可能多地提供细节。

hgtggwj0

hgtggwj01#

您不需要在它们上循环并单独创建它们。 Plan.new(plan_params) 要完成这项工作,只需正确指定嵌套属性。变化: daysday_attributes 不需要通过身份证。
例如:

  1. {
  2. "name": "Test Plan",
  3. "monthly_price": 0,
  4. "image_url": null,
  5. "day_attributes": [
  6. {
  7. "number": 1,
  8. "meal_attributes": [
  9. {
  10. "name": "Kale Salad",
  11. "calories": null,
  12. "protein": null,
  13. "fat": null,
  14. "carbohydrates": null,
  15. "image_url": null,
  16. "categorie": "snack-1"
  17. },
  18. {
  19. "name": "Fit Burger",
  20. "calories": null,
  21. "protein": null,
  22. "fat": null,
  23. "carbohydrates": null,
  24. "image_url": null,
  25. "categorie": "meal-1"
  26. },
  27. {
  28. "name": "Vegan Rataouille",
  29. "calories": null,
  30. "protein": null,
  31. "fat": null,
  32. "carbohydrates": null,
  33. "image_url": null,
  34. "categorie": "snack-2"
  35. },
  36. {
  37. "name": "Chicken BBQ",
  38. "calories": null,
  39. "protein": null,
  40. "fat": null,
  41. "carbohydrates": null,
  42. "image_url": null,
  43. "categorie": "meal-3"
  44. }
  45. ]
  46. },
  47. {
  48. "number": 2,
  49. "meal_attributes":
  50. [
  51. {
  52. "name": "Woldrof Salad",
  53. "calories": null,
  54. "protein": null,
  55. "fat": null,
  56. "carbohydrates": null,
  57. "image_url": null,
  58. "categorie": "snack-1"
  59. },
  60. {
  61. "name": "Baked Beef",
  62. "calories": null,
  63. "protein": null,
  64. "fat": null,
  65. "carbohydrates": null,
  66. "image_url": null,
  67. "categorie": "meal-1"
  68. }
  69. ]
  70. }
  71. ]

}
您还可以在许可参数中正确传递它们,如:

  1. params.permit(:name, :monthly_price, :image_url, day_attributes: [:number, meal_attributes: [:name, :calories, :protein, :fat, :carbohydrates, :image_url, :categorie]])

有关更多信息,请参阅:https://api.rubyonrails.org/v3.2/classes/activerecord/nestedattributes/classmethods.html

展开查看全部

相关问题