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

时间:2016-08-17 11:55:39

标签: ruby-on-rails ruby models relationships

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

我通过为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。

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

https://github.com/kingdavidek/StuddyBuddy

2 个答案:

答案 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_manybelongs_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