Reputation: 60110
I'm building a small Ruby application using DataMapper and Sinatra, and I'm trying to define a basic blog model:
I'm running into trouble getting the self-referential relation between comments going due to the fact that each Comment belongs_to
a Post. My classes right now look like this:
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
I'm following the guide at Associations and building a new object (CommentConnection) to link two comments together, but my issue is that each subcomment shouldn't belong to a Post as implied by the Comment class.
My first instinct was to extract out a superclass for Comments, so that one subclass could be "top-level" and belong to a post, while the other kind of comment belongs to another comment. Unfortunately, when I do that I run into issues with the comment IDs becoming null.
What's the best way to model this kind of recursive comment relationship in DataMapper?
Upvotes: 0
Views: 907
Reputation: 14035
What you need is a self referential join in Comments, e.g., each Comment can have a parent comment. Try the following:
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
This will allow you to have replies to any given comment, although accessing them may get a little nasty (slow) if the volume gets high. If you get this working and want something more sophisticated you could look at nested sets, I believe there is a nested sets plugin for DataMapper but I haven't used.
Upvotes: 5