Search code examples
ruby-on-railsrubyactiverecordruby-on-rails-5single-table-inheritance

Validation Failed when using accepts_nested_attributes_for with Single Table Inheritance


First time I'm using STI, and I'm running into issues when trying to use accepts_nested_attributes_for with nested inherited objects.

class Document < ApplicationRecord
  # code removed for brevity
end

class DocumentItem < ApplicationRecord
   # code removed for brevity
end

class Package < Document
    belongs_to :user
    validates :title, :user, presence: true

    has_many :package_items, dependent: :destroy
    accepts_nested_attributes_for :package_items, reject_if: :all_blank, allow_destroy: true
end

class PackageItem < DocumentItem
    belongs_to :package
end

When I try and use nested attributes, things stop working:

Package.create!(title: 'test', 
                user: User.last, 
                package_items_attributes: [{title: 'test'}])

Which results in the following error:

ActiveRecord::RecordInvalid: Validation failed: Package items package must exist

I've tried setting foreign_key and class_name on the belongs_to relationship, with no luck:

class PackageItem < DocumentItem
    belongs_to :package, foreign_key: 'document_id', class_name: 'Document'
end

What am I doing wrong here?

UPDATE:

This seems to be an issue with Rails 5 and associations having required: true by default. When turning off required: true and setting foreign_key on the Invoice model, it correctly assigns the parent model ID and saves the parent model and child models.


Solution

  • Turns out it has nothing to do with STI, and is a known Rails 5 bug. :(

    https://github.com/rails/rails/issues/25198