DataMapper子类化&多对多的自我指涉关系

时间:2010-12-10 19:50:53

标签: ruby recursion sinatra datamapper

我正在使用DataMapper和Sinatra构建一个小型Ruby应用程序,我正在尝试定义一个基本的博客模型:

  • 博客有多个用户
  • 我有一组帖子,每个帖子都由用户发布
  • 每个帖子都有一组评论
  • 每个评论都可以有自己的评论集 - 这可以重复多个级别

由于每个评论belongs_to发布一个帖子,因此我发现评论之间存在自我引用关系时遇到了麻烦。我的课程现在看起来像这样:

class User
  include DataMapper::Resource
  property :id, Serial
  property :username, String
  property :password, String

  has n, :post
end
class Post
  include DataMapper::Resource
  property :id, Serial
  property :content, Text

  belongs_to :user

  has n, :comment
end
class Comment
  include DataMapper::Resource
  property :id, Serial
  property :content, Text

  belongs_to :user
  belongs_to :post
end

我正在关注Associations的指南并构建一个新对象(CommentConnection)以将两个注释链接在一起,但我的问题是每个子注释不应属于Comment类隐含的Post。

我的第一直觉是为Comments提取一个超类,以便一个子类可以是“顶级”并属于一个帖子,而另一种类型的注释属于另一个注释。不幸的是,当我这样做时,我遇到的问题是注释ID变为空。

在DataMapper中建模这种递归注释关系的最佳方法是什么?

1 个答案:

答案 0 :(得分:5)

您需要的是评论中的自引用加入,例如,每个评论都可以有父评论。请尝试以下方法:

class Comment
  include DataMapper::Resource
  property :id, Serial
  property :content, Text

  has n, :replies, :child_key => [ :original_id ]
  belongs_to :original,  self, :required => false #Top level comments have none.
  belongs_to :user
  belongs_to :post
end

这将允许您回复任何给定的评论,但如果音量变高,访问它们可能会有点讨厌(慢)。如果你得到这个工作并想要更复杂的东西你可以看看嵌套集,我相信有一个嵌套的插件用于DataMapper,但我还没有用过。