将许多现有模型链接到一个新模型。 Ruby 在 Rails

Linking many existing models to one new one. Ruby on Rails

所以我正在制作一个评论书籍、文章等的应用程序。

我通过为 Piece(书籍或文章)、Section(不言自明)、Subsection 和 Subsubsection 创建模型、视图、控制器等来创建应用程序的 backbone。

我想在组合中添加一个新模型,一个 "Links" 模型(它只是 link 到另一个来源或网站)。我的问题是我不知道如何使我之前声明的所有模型都具有 "Links"。我希望上述每个模型都可以访问它们的 "Links" 并具有 CRUD 功能,但到目前为止我所读到的只是 has_many 或 has_and_belongs_to_many。

据我了解,这些关系只涉及一个模型与另一个模型,即使 Piece 可能有很多 Sections,它也只涉及这两个模型。

我想 Links 模型必须有一个强制性的 piece_id,但是可选的 ID 例如:section_id、subsection_id 取决于 link 的位置曾是。因此,如果我想在我的第一本书的第 3 章中添加一个 link,它将有一个强制性的 piece_id=1,然后是一个 section_id=3,但没有子 section_id 或 subsubsection_id.

那么我该如何创建一个模型,使其属于其他几个模型呢?或者这甚至可能吗?

https://github.com/kingdavidek/StuddyBuddy

好的,听起来您基本上想要一个 polymorphic association

class Link
  belongs_to :linkable, polymorphic: true
end

class Piece
  has_many :links, as: :linkable
end

Link 需要 linkable_id 整数列和 linkable_type 字符串列。然后,您可以像普通的 has_manybelongs_to 关联一样使用它

if i wanted to create a new Link in a Subsection, it would belong to Subsection, but also to Section and Piece because of the nested relationship

这点rails帮不上忙,你需要自己写一个方法来找到项目链中的所有链接。

这是 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 table 将有 linkable_id (int) 和 linkable_type (string) 列。此处需要注意的一件重要事情是,从 RBDMS 的角度来看,linkable_id 不是真正的外键。而是 ActiveRecord 在加载关系时解析 table 关系指向哪个。

如果我们想减少重复,我们可以创建一个包含所需行为的模块。使用 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

附带说明 - 在部分之间构建层次结构的更好方法是使用单个部分模型和 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