Rails应用程序中复杂数据结构的遍历

时间:2012-04-08 17:43:56

标签: ruby ruby-on-rails-3 database-design iteration tree-traversal

我有一个数据结构,其中主题具有子主题,再次具有子主题,从原始主题继续下降大约六个级别。这些主题中的每一个都有多个子主题。 我正在寻找一种方法来遍历这些数据,并带回每个子主题附属的数据......好像在拉动我想要的数据"下游"。

For example Given a topic structure:
Harry_Potter > Characters > Slitherin_House.videos  

(假设slitherin house有每个成员的子主题,Malfoy,Crabbe等)我希望每个成员的视频出现在Slitherin_House,Characters和Harry_Potter(每个祖先)的视频列表中)。

我一直在四处寻找并偶然发现AncestryActs As Tree,并仔细阅读代码并尝试使用它们,但它们看起来更像是围绕着祖先的一面,而不是从孩子那里获取和提取数据。

我也尝试过使用关联

 has_many :through, and has_and_belongs_to_many 

但是我尝试创建一个有效的遍历系统却没有成功。并且似乎无法完成如何做到这一点。

对于这样的困境,有没有人有任何想法或建议?或者知道提供任何此类功能的宝石?

关系类& model :(因为它应该像流一样流动)

class CreateStreams < ActiveRecord::Migration
  def change
    create_table :streams do |t|
      t.integer :downstream_id
      t.integer :upstream_id

      t.timestamps
    end

    add_index :streams, :downstream_id
    add_index :streams, :upstream_id
    add_index :streams, [:downstream_id, :upstream_id], unique: true
  end
end





# == Schema Information
#
# Table name: streams
#
#  id            :integer         not null, primary key
#  downstream_id :integer
#  upstream_id   :integer
#  created_at    :datetime        not null
#  updated_at    :datetime        not null
#

class Stream < ActiveRecord::Base
  attr_accessible :downstream_id

  belongs_to :subsidiary, class_name: "Topic"
  belongs_to :tributary, class_name: "Topic"

  validates :downstream_id, presence: true
  validates :upstream_id, presence: true

end

主题模型

# == Schema Information
#
# Table name: topics
#
#  id         :integer         not null, primary key
#  name       :string(255)
#  created_at :datetime        not null
#  updated_at :datetime        not null
#  slug       :string(255)
#  wiki       :string(255)
#  summary    :string(255)

class Topic < ActiveRecord::Base
  extend FriendlyId
  attr_accessible :name, :wiki, :summary

  has_many :streams, foreign_key: "downstream_id", dependent: :destroy
  has_many :tributaries, through: :streams, source: :tributary
  has_many :reverse_streams, foreign_key: "upstream_id",
                             class_name:  "Stream", 
                             dependent:   :destroy
  has_many :subsidiaries, :through => :reverse_streams, source: :subsidiary


  friendly_id :name, use: :slugged

  validates :name, presence: true, length: { maximum: 50 },
                   uniqueness: { case_sensitive: false }

  def downstream?(other_topic)
    streams.find_by_downstream_id(other_topic.id)
  end

  def flow!(other_topic)
    streams.create!(downstream_id: other_topic.id)
  end

  def dam!(other_topic)
    streams.find_by_downstream_id(other_topic.id).destroy
  end
end

注意:我还希望能够分配子主题,多个父项。因此角色可能会被放置在&#34; Actors&#34;例如。

1 个答案:

答案 0 :(得分:0)

如果你想以一种简单的方式设置它,我会寻求递归关系。这意味着主题可以属于另一个主题(嵌套)

该主题的数据库模型如下所示:

主题

  • ID
  • topic_id
  • 标题

模型将是:

class Topic < ActiveRecord::Base
  belongs_to :topic
  has_many :topics
end

现在,如果你有一个主题。您可以通过.topic及其.topics的孩子访问其父母。没有父级的主题是顶级主题,没有子主题的主题是结束节点。