Как сохранить данные в отношении корыта has_many из API? - PullRequest
0 голосов
/ 12 ноября 2018

Я делаю Ruby on Rails API.У меня есть две модели plans и categories, которые имеют отношение «многие ко многим», поэтому я использую промежуточную таблицу с моделью под названием category_plans.Я хочу создать план со многими категориями, и у каждой из них есть еще два атрибута (kind, portion), которые будут сохранены в промежуточной таблице.(Я использую 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

КатегорияPlan

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

КатегорияPlan

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

Я не уверен, что "сильные параметры" тоже правильныеЯ не уверен, как сделать мою структуру JSON, в настоящее время я получил это так:

JSON

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

1 Ответ

0 голосов
/ 13 ноября 2018

Ваш отправленный 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 на наличие ошибок, если это не удалось после этого.

...