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

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

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

class Plan < ApplicationRecord
  has_many :days
  accepts_nested_attributes_for :days
end

day.rb

class Day < ApplicationRecord
  has_many :meals
  belongs_to :plan
  accepts_nested_attributes_for :meals
end

膳食.rb

class Meal < ApplicationRecord
  belongs_to :plan
  belongs_to :day
end

这是plans_controller.rb中的方法


# POST /create_custon_plan

def create_custon_plan
  @plan = Plan.new(plan_params)
  @days = @plan.days
  @meals = Meal.where("plan_id = ? ", @plan.id)
    if @plan.save
      @days.each do |day|
        day = Day.find_or_create_by!(name: params[:number], plan_id: @plan.id) if params[:number].present?
        if day.save
          @meals.each do |meal|
            meal = Meal.find_or_create_by!(name: params[:name], plan_id: @plan.id, day_id: day.id) if params[:name].present?
            if meal.save
              render json: {
                       messages: "meals was successfully created.",
                       is_success: true,
                       status: :created,
                       data: { meal: meal },
                     }
            else
              render json: meal.errors, status: :unprocessable_entity
            end
          end
          render json: {
                   messages: "days was successfully created.",
                   is_success: true,
                   status: :created,
                   data: { day: day },
                 }
        else
          render json: day.errors, status: :unprocessable_entity
        end
      end
      render json: {
        messages: "Plan was successfully created.",
        is_success: true,
        status: :created,
        data: { plan: @plan, days: @days, meals: @meals },
      }
    else
      render json: @plan.errors, status: :unprocessable_entity
    end
  end

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

{
    "name": "Test Plan",
    "monthly_price": 0,
    "image_url": null,
    "days": [
                {
                "number": 1,
                "plan_id": 4,
                "meals": [
                            {
                                "id": 269,
                                "name": "Kale Salad",
                                "calories": null,
                                "protein": null,
                                "fat": null,
                                "carbohydrates": null,
                                "plan_id": 4,
                                "image_url": null,
                                "categorie": "snack-1"
                            },
                            {
                                "id": 270,
                                "name": "Fit Burger",
                                "calories": null,
                                "protein": null,
                                "fat": null,
                                "carbohydrates": null,
                                "plan_id": 4,
                                "image_url": null,
                                "categorie": "meal-1"
                            },
                            {
                                "id": 271,
                                "name": "Vegan Rataouille",
                                "calories": null,
                                "protein": null,
                                "fat": null,
                                "carbohydrates": null,
                                "plan_id": 4,
                                "image_url": null,
                                "categorie": "snack-2"
                            },
                            {
                                "id": 272,
                                "name": "Chicken BBQ",
                                "calories": null,
                                "protein": null,
                                "fat": null,
                                "carbohydrates": null,
                                "plan_id": 4,
                                "image_url": null,
                                "categorie": "meal-3"
                            }
                        ]
                },
                {
                "number": 2,
                "plan_id": 4,
                "meals": 
                        [
                            {
                                "id": 273,
                                "name": "Woldrof Salad",
                                "calories": null,
                                "protein": null,
                                "fat": null,
                                "carbohydrates": null,
                                "plan_id": 4,
                                "image_url": null,
                                "categorie": "snack-1"
                            },
                            {
                                "id": 274,
                                "name": "Baked Beef",
                                "calories": null,
                                "protein": null,
                                "fat": null,
                                "carbohydrates": null,
                                "plan_id": 4,
                                "image_url": null,
                                "categorie": "meal-1"
                            }
                        ]
                }
            ]
}

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

Started POST "/api/create_custon_plan" for ::1 at 2021-07-23 15:43:08 +0100
   (0.9ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
Processing by PlansController#create_custon_plan as */*
  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}}
Can't verify CSRF token authenticity.
  TRANSACTION (0.3ms)  BEGIN
  ↳ app/models/plan.rb:13:in `acceptable_image'
  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"]]
  ↳ app/controllers/plans_controller.rb:42:in `create_custon_plan'
  TRANSACTION (1.0ms)  COMMIT
  ↳ app/controllers/plans_controller.rb:42:in `create_custon_plan'
  Day Load (1.7ms)  SELECT "days".* FROM "days" WHERE "days"."plan_id" = $1  [["plan_id", 34]]
  ↳ app/controllers/plans_controller.rb:43:in `create_custon_plan'
[active_model_serializers]   Meal Load (2.9ms)  SELECT "meals".* FROM "meals" WHERE (plan_id = NULL )
[active_model_serializers]   ↳ app/controllers/plans_controller.rb:69:in `create_custon_plan'
[active_model_serializers] Rendered ActiveModel::Serializer::Null with Hash (5.92ms)
Completed 200 OK in 49ms (Views: 5.3ms | ActiveRecord: 13.8ms | Allocations: 14452)

最后是请求的返回体

{
    "messages": "Plan was successfully created.",
    "is_success": true,
    "status": "created",
    "data": {
        "plan": {
            "id": 34,
            "name": "Test Plan",
            "monthly_price": 0,
            "created_at": "2021-07-23T14:43:08.845Z",
            "updated_at": "2021-07-23T14:43:08.845Z",
            "is_custom": null
        },
        "days": [],
        "meals": []
    }
}

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

hgtggwj0

hgtggwj01#

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

{
"name": "Test Plan",
"monthly_price": 0,
"image_url": null,
"day_attributes": [
            {
            "number": 1,
            "meal_attributes": [
                        {
                            "name": "Kale Salad",
                            "calories": null,
                            "protein": null,
                            "fat": null,
                            "carbohydrates": null,
                            "image_url": null,
                            "categorie": "snack-1"
                        },
                        {
                            "name": "Fit Burger",
                            "calories": null,
                            "protein": null,
                            "fat": null,
                            "carbohydrates": null,
                            "image_url": null,
                            "categorie": "meal-1"
                        },
                        {
                            "name": "Vegan Rataouille",
                            "calories": null,
                            "protein": null,
                            "fat": null,
                            "carbohydrates": null,
                            "image_url": null,
                            "categorie": "snack-2"
                        },
                        {
                            "name": "Chicken BBQ",
                            "calories": null,
                            "protein": null,
                            "fat": null,
                            "carbohydrates": null,
                            "image_url": null,
                            "categorie": "meal-3"
                        }
                    ]
            },
            {
            "number": 2,
            "meal_attributes": 
                    [
                        {
                            "name": "Woldrof Salad",
                            "calories": null,
                            "protein": null,
                            "fat": null,
                            "carbohydrates": null,
                            "image_url": null,
                            "categorie": "snack-1"
                        },
                        {
                            "name": "Baked Beef",
                            "calories": null,
                            "protein": null,
                            "fat": null,
                            "carbohydrates": null,
                            "image_url": null,
                            "categorie": "meal-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

相关问题