如何将数据保存在 API 的 "has_many trough" 关系中?

How to save data in a "has_many trough" relation from API?

我正在 Rails API 上做 Ruby。我有两个模型 planscategories,它们具有关系 "many to many",所以我使用一个中间 table 和一个名为 category_plans 的模型。我想要的是创建一个有很多类别的计划,并且每个类别都有两个属性(kindportion),这些属性将保存在中间table上。 (我正在使用 Postgresql)。

类别

class Category < ApplicationRecord
    has_many :category_plans
    has_many :plan, through: :category_plans
end

计划

class Plan < ApplicationRecord
    has_many :category_plans
    has_many :category, through: :category_plans
end

类别计划

class CategoryPlan < ApplicationRecord
    validates_presence_of :category, :plan

    enum kind: {
        Colacion: 'Colacion',
        Desayuno: 'Desayuno',
        Comida: 'Comida',
        Cena: 'Cena'
    }, _prefix: :kind

    belongs_to :category
    belongs_to :plan
end

这些是我使用的迁移:

计划

class CreatePlans < ActiveRecord::Migration[5.2]
    def change
        create_table :plans do |t|
            t.string :name
            t.references :patient, foreign_key: true
            t.text :description
            t.datetime :deleted_at
            t.timestamps
        end
    end
end

类别

class CreateCategories < ActiveRecord::Migration[5.2]
    def change
        create_table :categories do |t|
            t.string :name
            t.timestamps
        end
    end
end

类别计划

class CreateCategoryPlans < ActiveRecord::Migration[5.2]
    def up
        execute <<-SQL
            CREATE TYPE type_food AS ENUM ('Colacion', 'Desayuno', 'Comida', 
            'Cena');
        SQL

        create_table :category_plans do |t|
            t.belongs_to :category, :null => false, :index => true
            t.belongs_to :plan, :null => false, :index => true
            t.column :kind  , :type_food
            t.float :portion
        end
        add_index :category_plans, :kind
    end

    def down
        drop_column :kind, :type_food
        execute "DROP kind type_food;"
    end
end

控制器:

class V1::PlansController < ApplicationController
    before_action :set_patient, only: [:show, :update, :destroy]

    def create
        plan = Plan.new(plan_params)
        if plan.save
            render json: {status: 'Success', message: 'Saved plan', data: 
            plan}, status: 201
        else
            render json: {status: 'Error', message: 'Plan not saved', data: 
            plan.errors}, status: :unprocessable_entity
        end
    end

    def plan_params
        params.require(:plan).permit(:name, :patient_id, :description, 
        category_plans_attributes: [:id, :kind, :portion, 
        category_attributes: [:id]])
    end

end

我不确定"strong params"是否正确,我也不确定如何做我的JSON结构,此时我是这样得到的:

JSON

{
    "plan": {
        "name": "Plan 8",   
        "patient_id": "3",
        "description": "Plan nuevo",
        "category_plan": {
            "kind": "Cena",
            "portion": "12.3"
        }
    } 
}

您提交的 JSON 需要与 plan_params

中允许的属性相同
{
    "plan": {
        "name": "Plan 8",   
        "patient_id": "3",
        "description": "Plan nuevo",
        "category_plans_attributes": [{
            "kind": "Cena",
            "portion": "12.3"
        }]
    } 
}

您还需要将 accepts_nested_attributes_for : category_plans 添加到 Plan 模型。

尝试并检查 rails 应用日志是否有错误,如果在此之后没有成功。