给定ContentBlock
模型:
class ContentBlock < ActiveRecord::Base
has_one :block_association
has_one :image, through: :block_association, source: :content, source_type: "Image"
has_one :snippet, through: :block_association, source: :content, source_type: "Snippet"
accepts_nested_attributes_for :image, allow_destroy: true
accepts_nested_attributes_for :snippet, allow_destroy: true
end
BlockAssociation模型:
class BlockAssociation < ActiveRecord::Base
belongs_to :content_block
belongs_to :content, polymorphic: true
end
代码段模型:
class Snippet < ActiveRecord::Base
has_one :block_association, as: :content
has_one :content_block, through: :block_association
validates :body, presence: true
end
我需要这样做:
@content_block.build_snippet
但这给出了:
undefined method 'build_snippet' for #<ContentBlock:0x007ffb7edde330>
我如何达到预期的效果?
表格将是这样的:
<%= simple_form_for @content_block do |f| %>
<%= f.simple_fields_for f.object.snippet || f.object.build_snippet do |sf| %>
<%= sf.input :body %>
<% end %>
<% end %>
(最初我假设content_block
只是belong_to :content, polymorphic: true
,但由于多种content
类型,这似乎不合适。)
这与我正在做的很接近,但我无法理解它:http://xtargets.com/2012/04/04/solving-polymorphic-hasone-through-building-and-nested-forms/
答案 0 :(得分:0)
class ContentBlock < ActiveRecord::Base
has_one :snippet, through: :block_association, source: :content, source_type: "Snippet"
end
这告诉rails,你想要ContentBlock的实例(让这个实例使content_block)通过BlockAssociation有一个名为“snippet”的假类型“内容”的Snippet实例。因此,ContentBlock实例应该能够响应content_block.content,这将返回片段和/或图像的集合(我在代码片段中省略了图像部分)。 content_block如何只能调用尚无人知道的片段内容。
您的BlockAssociation模型知道什么:
class BlockAssociation < ActiveRecord::Base
belongs_to :content_block
belongs_to :content, polymorphic: true
end
它知道它属于content_block并且知道(因为它将响应内容)一个或多个内容具有content_type('Snippet')和content_id(1或任何片段id),这些组合与片段的关系
现在你缺少的是Snippet部分:
class Snippet < ActiveRecord::Base
has_one :block_association, :as => :snippet_content
has_one :content_block, :through => :content_association # I'm actually not quite sure of this
end
告诉block_association如何调用此类内容,因为您希望图像内容和代码段内容不同。现在content_block.snippet_content应该返回代码段,snippet.block_content应该返回block_content。
我希望我没有弄乱任何东西,这些关系总是让我头晕目眩