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












1














I'm doing a Ruby on Rails API. I have two models plans and categories, which has a relation "many to many" so I use an intermediate table with a model called category_plans. What I want is to create a plan with many categories, and each one of them has two more attributes (kind, portion) which will be saved on the intermediate table. (I'm using Postgresql).



Category



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


Plan



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


CategoryPlan



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


These are the migrations I use:



Plan



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


Category



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


CategoryPlan



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


And the controller:



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


I'm not sure that "strong params" is right, also I'm not sure about how to do my JSON structure, at this time I got it like this:



JSON



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









share|improve this question



























    1














    I'm doing a Ruby on Rails API. I have two models plans and categories, which has a relation "many to many" so I use an intermediate table with a model called category_plans. What I want is to create a plan with many categories, and each one of them has two more attributes (kind, portion) which will be saved on the intermediate table. (I'm using Postgresql).



    Category



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


    Plan



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


    CategoryPlan



    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


    These are the migrations I use:



    Plan



    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


    Category



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


    CategoryPlan



    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


    And the controller:



    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


    I'm not sure that "strong params" is right, also I'm not sure about how to do my JSON structure, at this time I got it like this:



    JSON



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









    share|improve this question

























      1












      1








      1







      I'm doing a Ruby on Rails API. I have two models plans and categories, which has a relation "many to many" so I use an intermediate table with a model called category_plans. What I want is to create a plan with many categories, and each one of them has two more attributes (kind, portion) which will be saved on the intermediate table. (I'm using Postgresql).



      Category



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


      Plan



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


      CategoryPlan



      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


      These are the migrations I use:



      Plan



      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


      Category



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


      CategoryPlan



      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


      And the controller:



      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


      I'm not sure that "strong params" is right, also I'm not sure about how to do my JSON structure, at this time I got it like this:



      JSON



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









      share|improve this question













      I'm doing a Ruby on Rails API. I have two models plans and categories, which has a relation "many to many" so I use an intermediate table with a model called category_plans. What I want is to create a plan with many categories, and each one of them has two more attributes (kind, portion) which will be saved on the intermediate table. (I'm using Postgresql).



      Category



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


      Plan



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


      CategoryPlan



      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


      These are the migrations I use:



      Plan



      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


      Category



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


      CategoryPlan



      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


      And the controller:



      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


      I'm not sure that "strong params" is right, also I'm not sure about how to do my JSON structure, at this time I got it like this:



      JSON



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






      ruby-on-rails api database-relations






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 12 at 19:22









      Emmanuel González

      82




      82
























          1 Answer
          1






          active

          oldest

          votes


















          0














          Your submitted JSON needs to be the same as the permitted attributes in plan_params



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


          Also you need to add the accepts_nested_attributes_for : category_plans to the Plan model.



          Try that and check the rails app logs for errors if it does not succeed after this.






          share|improve this answer





















          • Thank you so much, it works!!
            – Emmanuel González
            Nov 13 at 16:51











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53268770%2fhow-to-save-data-in-a-has-many-trough-relation-from-api%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














          Your submitted JSON needs to be the same as the permitted attributes in plan_params



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


          Also you need to add the accepts_nested_attributes_for : category_plans to the Plan model.



          Try that and check the rails app logs for errors if it does not succeed after this.






          share|improve this answer





















          • Thank you so much, it works!!
            – Emmanuel González
            Nov 13 at 16:51
















          0














          Your submitted JSON needs to be the same as the permitted attributes in plan_params



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


          Also you need to add the accepts_nested_attributes_for : category_plans to the Plan model.



          Try that and check the rails app logs for errors if it does not succeed after this.






          share|improve this answer





















          • Thank you so much, it works!!
            – Emmanuel González
            Nov 13 at 16:51














          0












          0








          0






          Your submitted JSON needs to be the same as the permitted attributes in plan_params



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


          Also you need to add the accepts_nested_attributes_for : category_plans to the Plan model.



          Try that and check the rails app logs for errors if it does not succeed after this.






          share|improve this answer












          Your submitted JSON needs to be the same as the permitted attributes in plan_params



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


          Also you need to add the accepts_nested_attributes_for : category_plans to the Plan model.



          Try that and check the rails app logs for errors if it does not succeed after this.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 12 at 23:11









          Simon Brazell

          35217




          35217












          • Thank you so much, it works!!
            – Emmanuel González
            Nov 13 at 16:51


















          • Thank you so much, it works!!
            – Emmanuel González
            Nov 13 at 16:51
















          Thank you so much, it works!!
          – Emmanuel González
          Nov 13 at 16:51




          Thank you so much, it works!!
          – Emmanuel González
          Nov 13 at 16:51


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53268770%2fhow-to-save-data-in-a-has-many-trough-relation-from-api%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Xamarin.iOS Cant Deploy on Iphone

          Glorious Revolution

          Dulmage-Mendelsohn matrix decomposition in Python