简短回答
添加图片和视频模型:
accepts_nested_attributes_for :content
证明
我很确定我知道这个问题的答案,但不确定它是否适用于多态关联(我以前没有使用过),所以我设置了一个小测试。
创建了与你设置相同的模型,但加上了名称属性,并且添加了一个验证来测试失败情况。
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
接下来按照以下方式设置迁移:
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
接下来编写一个RSpec测试,以确保如果子对象无法保存,则父对象不会被保存,并且验证错误会向上传递。
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
我进行了测试,结果失败了。
接下来,将以下行添加到图像(和视频)中。
accepts_nested_attributes_for :content
测试现在是通过的 - 即如果子级未通过验证,则父级也将未通过验证,并且不会保存。
Image
并保存它,然后再添加一个子对象,Rails 无法撤消此次save
操作。那么你就需要将所有操作封装在一个事务中,并抛出错误来触发回滚。 - slowjack2k