Search code examples
ruby-on-railspostgresqlactiveadminformtastic

Rails, formtastic and postgres: NotNullViolation


this one isnt googling at all, so i have no choice but to bother you with such braincracker.

I have 2 models, linked through HMT. I also have ActiveAdmin. When I try to create object from 1st model, postgres shoots NotNullViolation, because, well, rails tries to make join without actually inserting ID of created object in joins table.

Like this:

SQL (0.9ms)  INSERT INTO "project_stone_joins" ("stone_id") VALUES ($1)  [["stone_id",2]]
PG::NotNullViolation: ERROR:  null value in column "project_id" violates not-null constraint
DETAIL:  Failing row contains (null, 2).: INSERT INTO "project_stone_joins" ("stone_id") VALUES ($1)
   (0.4ms)  ROLLBACK

The pointy thing is: changing doing just fine. No joke, siree, it's doing great.

   (0.3ms)  BEGIN
SQL (0.7ms)  DELETE FROM "project_stone_joins" WHERE "project_stone_joins"."project_id" = $1 AND "project_stone_joins"."stone_id" = 4  [["project_id", 10]]
SQL (0.3ms)  INSERT INTO "project_stone_joins" ("project_id", "stone_id") VALUES ($1, $2)  [["project_id", 10], ["stone_id", 2]]
SQL (0.3ms)  INSERT INTO "project_stone_joins" ("project_id", "stone_id") VALUES ($1, $2)  [["project_id", 10], ["stone_id", 3]]
SQL (0.3ms)  INSERT INTO "project_stone_joins" ("project_id", "stone_id") VALUES ($1, $2)  [["project_id", 10], ["stone_id", 16]]
SQL (0.3ms)  INSERT INTO "project_stone_joins" ("project_id", "stone_id") VALUES ($1, $2)  [["project_id", 10], ["stone_id", 17]]
SQL (0.3ms)  INSERT INTO "project_stone_joins" ("project_id", "stone_id") VALUES ($1, $2)  [["project_id", 10], ["stone_id", 28]]
SQL (0.4ms)  INSERT INTO "project_stone_joins" ("project_id", "stone_id") VALUES ($1, $2)  [["project_id", 10], ["stone_id", 30]]
SQL (0.5ms)  INSERT INTO "project_stone_joins" ("project_id", "stone_id") VALUES ($1, $2)  [["project_id", 10], ["stone_id", 42]]
   (33.5ms)  COMMIT

So, rails actually forgets to put my project_id in project_stone_joins. Or I am overworked and not seeing something important. Here's models, schemas, etcetera.

SCHEMA.RB------------------------
  create_table "stones", force: true do |t|
    t.integer  "stone_material_id"
    t.string   "name"
    t.string   "cover_file_name"
    t.string   "cover_content_type"
    t.integer  "cover_file_size"
    t.datetime "cover_updated_at"
    t.boolean  "render"
  end

  create_table "projects", force: true do |t|
    t.string   "name"
    t.integer  "project_group_id"
    t.text     "description"
    t.string   "cover_file_name"
    t.string   "cover_content_type"
    t.integer  "cover_file_size"
    t.datetime "cover_updated_at"
    t.boolean  "ours"
  end

  create_table "project_stone_joins", id: false, force: true do |t|
    t.integer "project_id", null: false
    t.integer "stone_id",   null: false
  end

PROJECT.RB-MODELS--------------------
class Project < ActiveRecord::Base
  belongs_to :project_group
  has_many :project_photos
  has_many :project_stone_joins, dependent: :destroy
  has_many :stones, through: :project_stone_joins

  has_attached_file :cover,
                    styles: {thumb: '100x100#', medium:'300x300#'},
                    default_url: 'project_covers/:style/missing.png'
  validates_attachment_content_type :cover,
                                    content_type: /\Aimage\/.*\Z/

  accepts_nested_attributes_for :project_stone_joins

end
PROJECT.RB-ADMIN------------------
ActiveAdmin.register Project do
  permit_params :name, :project_group_id, :description,
                :cover, :ours, stone_ids:[]

  form do |f|
    f.inputs do
      f.input :project_group
      f.input :stones
      f.input :name
      f.input :description
      f.input :cover, as: :file
      f.input :ours
    end
    f.actions
  end
end
STONE.RB-MODELS---------------------------
class Stone < ActiveRecord::Base
  belongs_to :stone_material
  has_many :stone_photos
  has_many :project_stone_joins, dependent: :destroy
  has_many :projects, through: :project_stone_joins
  has_many :varieties

  has_attached_file :cover,
                    styles: {thumb: '100x100#', medium:'300x300#'},
                    default_url: 'stone_covers/:style/missing.png'
  validates_attachment_content_type :cover,
                                    content_type: /\Aimage\/.*\Z/

  accepts_nested_attributes_for :project_stone_joins

end
STONE.RB-ADMIN------------------------------
ActiveAdmin.register Stone do
  permit_params :name, :stone_material_id, :cover, :render, project_ids: []

  form do |f|
    f.inputs do
      f.input :stone_material
      f.input :name
      f.input :cover, as: :file
      f.input :render
    end
    f.actions
  end
end
PROJECT_STONE_JOIN.RB-MODEL------------------
class ProjectStoneJoin < ActiveRecord::Base
  belongs_to :project
  belongs_to :stone
end

So, what's wrong? Actions are not restricted, yet creating doesnt works and updating do.


Solution

  • Alright, it seems to be known issue. It fixes with removing "accepts_nested_attributes_for" for join tables

    Also, make sure to not add dependent:destroy on has_many: joins, or it will also generate error. Here's more info. https://github.com/rails/rails/issues/16085