2

I'm currently working through the Ruby on Rails Essentials 5 training course on Lynda, and in the section on one-to-one associations, I create a "Subject" that has_one "Page." Each model looks like the following:

class Subject < ApplicationRecord

    has_one :page

    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

/////

class Page < ApplicationRecord

    belongs_to :subject

end

In the db, I have an existing Subject that I find by id and save to a variable. Then I create a new Page object (but not save it), and finally, I persist it by doing subject.page = page. The issue is, when I try to remove the association using subject.page = nil, I end up with the following error:

irb(main):004:0> subject.page = nil
   (0.3ms)  BEGIN
   (0.2ms)  ROLLBACK
ActiveRecord::RecordNotSaved: Failed to remove the existing associated 
page. The record failed to save after its foreign key was set to nil.
    from (irb):4

I believe the expected behavior is for the page record to have its foreign key reassigned to NULL. This behavior is reflected in the tutorial I'm using, and in other posts about the subject. What am I missing here?

1 Answers1

5

Since rails 5, the behaviour of belongs_to association has changed. It checks if the associated record persists, if not - throws an error.

If you want to keep page object without association you should add belongs_to :subject, optional: true

rubynuby
  • 83
  • 8
  • See: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-belongs_to-label-Options – 3limin4t0r Feb 28 '18 at 10:07