所以我正在制作一个评论书籍,文章等的应用程序。
我通过为Piece(书籍或文章),Section(自解释),Subsection和Subsubsection创建模型,视图,控制器等来创建应用程序的主干。
我想在混音中添加一个新模型,"链接" model(它只是一个链接到另一个源或网站)。我的问题是,我不知道如何使我之前提到的所有型号都具有"链接"。我希望上面的每个模型都能够访问" Links",但到目前为止,我所读到的只有has_many或has_and_belongs_to_many。
据我了解,这种关系只将ONE模型与其他模型联系起来,即使Piece可能有很多Sections,它只涉及这两个模型。
我猜Links模型必须有一个强制性的piece_id,但随后是可选的id,例如:section_id,subsection_id,具体取决于链接的位置。因此,如果在我的第一本书的第3章中我想添加一个链接,它将具有强制性的piece_id = 1然后是section_id = 3,但是没有subsection_id或subsubsection_id。
那么我该如何创建一个模型,使其属于其他几个模型呢?或者这甚至可能吗?
答案 0 :(得分:1)
好的,听起来基本上你想要一个polymorphic association
class Link
belongs_to :linkable, polymorphic: true
end
class Piece
has_many :links, as: :linkable
end
链接需要linkable_id
整数列和linkable_type
字符串列。然后,您可以使用与普通has_many
到belongs_to
关联
如果我想在子部分中创建一个新的链接,它将属于 分段,也因为嵌套而得分段 关系
这位bit无法帮助你,你需要编写自己的方法来查找项目链中的所有链接。
答案 1 :(得分:0)
这是polymorphic关联的一个很好的用例。为简单起见,我们从一对多的关系开始:
class Link < ActiveRecord::Base
belongs_to :linkable, polymorphic: true
end
class Piece < ActiveRecord::Base
has_many :links, as: :linkable
end
class Section < ActiveRecord::Base
has_many :links, as: :linkable
end
此处links
表将包含linkable_id
(int)和linkable_type
(字符串)列。这里需要注意的一件重要事情是,linkable_id
从RBDMS的角度来看并不是真正的外键。相反,ActiveRecord会解析关系在加载关系时指向哪个表。
如果我们想要减少重复,我们可以创建一个包含所需行为的模块。使用ActiveSupport::Concern会削减创建此类模块所涉及的许多样板代码。
class Link < ActiveRecord::Base
belongs_to :linkable, polymorphic: true
end
# app/models/concerns/linkable.rb
module Linkable
extend ActiveSupport::Concern
included do
has_many :links, as: :linkable
end
end
class Piece < ActiveRecord::Base
include Linkable
end
class Section < ActiveRecord::Base
include Linkable
end
那么我们如何制作多对多关系的多态?
class Link < ActiveRecord::Base
has_many :linkings
end
# this is the join model which contains the associations between
# Links and the "linkable" models
class Linking < ActiveRecord::Base
belongs_to :link
belongs_to :linkable, polymorphic: true
end
# app/models/concerns/linkable.rb
module Linkable
extend ActiveSupport::Concern
included do
has_many :links, through: :linkings, as: :linkable
end
end
class Piece < ActiveRecord::Base
include Linkable
end
class Section < ActiveRecord::Base
include Linkable
end
侧面说明 - 在部分之间构建层次结构的更好方法是使用单个Section模型和give it a self joining relationship。
class Section < ActiveRecord::Base
belongs_to :parent, class_name: 'Section'
has_many :children, class_name: 'Section',
foreign_key: 'parent_id'
end