In Rails 6.1 : "ActiveRecord::RecordNotSaved :Failed to remove the existing associated page."

Viewed 141

I want to remove the association between two tables using Nil command.

Subject model looks like subject.rb

class Subject < ApplicationRecord

has_one :page
# subject has one page

# scope :visible, -> { where(visible: true) }
# scope :invisible, -> { where(visible: false) }
# scope :sorted, -> { order("position ASC") }
# scope :newest_first, -> { order("created_at DESC") } 

scope :visible, lambda  { where(visible: true) }
scope :invisible, lambda  { where(visible: false) }
scope :sorted, lambda { order("position ASC") }
scope :newest_first, lambda { order("created_at DESC") } 
scope :search, lambda { |query| where(['name LIKE ?', "%#{query}%"]) }

end Page Model looks like

page.rb

 class Page < ApplicationRecord
 # foreign key
    belongs_to :subject
  end

Page migrated file looks like

20210919102818_create_pages.rb

class CreatePages < ActiveRecord::Migration[6.1]
def up
 create_table :pages do |t|

    t.integer "subject_id"
    t.string "name"
    t.string "permalink"
    t.integer "position"
    t.boolean "visible", default:false
    t.timestamps
   end
   add_index :pages, :subject_id
   add_index :pages, :permalink
 end
  def down
    drop_table :pages
   end
 end 

Subject migrated file looks like

20210919102807_create_subjects.rb

    class CreatePages < ActiveRecord::Migration[6.1]
  def up
    create_table :pages do |t|

      t.integer "subject_id"
      t.string "name"
      t.string "permalink"
      t.integer "position"
      t.boolean "visible", default:false
      t.timestamps
    end
    add_index :pages, :subject_id
    add_index :pages, :permalink
  end
  def down
    drop_table :pages
  end
end 

The error part for using nil. it is showing

ActiveRecord::RecordNotSaved (Failed to remove the existing associated page. The record failed to save after its foreign key was set to nil.)

Error Picture

Error Part

1 Answers

The reason, as explained in this blog, is because of a change to Rails 5+, where "belongs_to" have an implied presence validation which prevent it from being set to nil. The release notes offer a solution which is

belongs_to :subject, optional: true

in your case.

Related