Short Answer
Add to image and video model:
accepts_nested_attributes_for :content
The Proof
I was quite sure I knew the answer to this but wasn't sure if it worked with polymorphic associations (which I haven't used before) so I set up a small test.
Created the models the same way as you have yours setup but with a name attribute and with a validation that I can use to test for failure.
class Image < ActiveRecord::Base
has_one :content,
as: :contentable,
inverse_of: :contentable,
dependent: :destroy
validates_length_of :name, maximum: 10
end
class Content < ActiveRecord::Base
belongs_to :contentable,
inverse_of: :content,
polymorphic: true
validates_length_of :name, maximum: 10
end
Next setup the migrations as so:
class CreateImages < ActiveRecord::Migration
def change
create_table :images do |t|
t.string :name
t.timestamps null: false
end
end
end
class CreateContents < ActiveRecord::Migration
def change
create_table :contents do |t|
t.string :name
t.references :contentable, polymorphic: true, index: true
t.timestamps null: false
end
end
end
Next write an RSpec to test that the parent isn't saved if child can't be saved and that validation errors perculate up.
it 'should not save image if content is invalid' do
image = Image.new()
image.name = 'this is ok'
expect(image).to be_valid
content = Content.new()
content.name = 'a string that should fail validation'
image.content = content
expect(image).to_not be_valid
image.save
expect(image).to_not be_persisted
expect(content).to_not be_persisted
expect(image.errors.count).to eq(1)
expect(image.content.errors[:name][0]).to include('is too long')
end
Ran the test and sure enough it fails.
Next add the following line to image (and video)
accepts_nested_attributes_for :content
The tests now pass - i.e., if the child fails validation the parent will also fail validation and will not save.
Image
and save it and then add a child, Rails can't undo thissave
. Then you have to wrap every thing in a transaction and raise an error to trigger rollback. – slowjack2k