我正在开发一个API Ruby on rails 6.1应用程序,所以我所有的响应都是JSON格式的。我试图创建一个3级嵌套记录,这意味着我想创建一个计划记录,其中包含许多天的记录,其中包含每天的许多餐。
Plan.rb
class Plan < ApplicationRecord
has_and_belongs_to_many :days
has_and_belongs_to_many :meals
has_one_attached :image, dependent: :destroy
accepts_nested_attributes_for :meals, reject_if: ->(object) { object[:name].blank? }
accepts_nested_attributes_for :days, reject_if: ->(object) { object[:number].blank? }
end
Day.rb
class Day < ApplicationRecord
has_and_belongs_to_many :plans
has_and_belongs_to_many :meals
validates_presence_of :number, on: [:create, :update], message: "can't be blank"
validates_uniqueness_of :number, on: [:create, :update], message: "You can't use same day number twice"
accepts_nested_attributes_for :meals, reject_if: ->(object) { object[:name].blank? }
end
Meal.rb
class Meal < ApplicationRecord
has_and_belongs_to_many :days
has_and_belongs_to_many :plans
end
我还增加了2个join表
create_table "days_meals", id: false, force: :cascade do |t|
t.bigint "day_id", null: false
t.bigint "meal_id", null: false
end
create_table "days_plans", id: false, force: :cascade do |t|
t.bigint "day_id", null: false
t.bigint "plan_id", null: false
end
,这是更新后的plans_controller.rb
# POST /create_custon_plan
def create_custon_plan
@plan = Plan.new(plan_params)
if @plan.save
render json: {
messages: "Plan was successfully created.",
is_success: true,
status: :created,
data: { plan: @plan, days_attributes: @plan.days, meals_attributes: @plan.meals },
}
else
render json: @plan.errors, status: :unprocessable_entity
end
end
这就是我允许参数
的方式def plan_params
params.require(:plan).permit(:name, :monthly_price, :image_url, days_attributes: [:number, meals_attributes: [:name, :calories, :protein, :fat, :carbohydrates, :categorie]])
end
This is my POST请求正文到http://localhost:3000/api/create_custon_plan
{
"name": "Test Plan",
"monthly_price": 0,
"image_url": "55555",
"days_attributes": [
{
"number": 500,
"meals_attributes": [
{
"name": "azerazer Salad",
"calories": 55,
"protein": 55,
"fat": 55,
"carbohydrates": 55,
"image_url": "55555",
"categorie": "snack-1"
},
{
"name": "Fit Burger",
"calories": 55,
"protein": 55,
"fat": 55,
"carbohydrates": 55,
"image_url": "55555",
"categorie": "meal-1"
},
{
"name": "Vegan Rataouille",
"calories": 55,
"protein": 55,
"fat": 55,
"carbohydrates": 55,
"image_url": "55555",
"categorie": "snack-2"
},
{
"name": "Chicken BBQ",
"calories": 55,
"protein": 55,
"fat": 55,
"carbohydrates": 55,
"image_url": "55555",
"categorie": "meal-3"
}
]
},
{
"number": 502,
"meals_attributes":
[
{
"name": "Woldrof Salad",
"calories": 55,
"protein": 55,
"fat": 55,
"carbohydrates": 55,
"image_url": "55555",
"categorie": "snack-1"
},
{
"name": "Baked Beef",
"calories": 55,
"protein": 55,
"fat": 55,
"carbohydrates": 55,
"image_url": "55555",
"categorie": "meal-1"
}
]
}
]
}
到目前为止,嵌套的一天工作得很好,但嵌套的膳食内嵌套的日子没有任何想法如何解决这个问题?甚至终端内的日志也完全忽略它
您不需要在它们上循环并单独创建它们。Plan.new(plan_params)
应该完成这项工作,您只需要正确指定嵌套属性。
变化:
-
days
today_attributes
- 不需要传递id。 例如:
{
"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"
}
]
}
]
}
你也应该在permit参数中适当地提到它们,比如:
params.permit(:name, :monthly_price, :image_url, day_attributes: [:number, meal_attributes: [:name, :calories, :protein, :fat, :carbohydrates, :image_url, :categorie]])
更多信息请参考:
活动记录嵌套属性
Railscasts # 196