Создание подклассов DataMapper и самореферентные отношения "многие ко многим"

Я создаю небольшое приложение Ruby, используя DataMapper и Sinatra, и пытаюсь определить базовую модель блога:

  • У блога несколько пользователей
  • У меня есть коллекция сообщений, каждое из которых размещено пользователем.
  • У каждого сообщения есть набор комментариев.
  • Каждый комментарий может иметь свой собственный набор комментариев - он может повторяться на несколько уровней в глубину.

У меня возникают проблемы с установлением связи между комментариями со ссылками на самих себя из-за того, что каждый комментарий 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

Я следую руководству на странице Associates и создаю новый объект (CommentConnection), чтобы связать два комментария вместе, но Моя проблема в том, что каждый подкомментарий не должен принадлежать сообщению, как подразумевается классом комментариев.

Моим первым побуждением было выделить суперкласс для комментариев, чтобы один подкласс мог быть «верхнего уровня» и принадлежать сообщению, а другой тип комментариев принадлежал другому комментарию. К сожалению, когда я это делаю, я сталкиваюсь с проблемами, когда идентификаторы комментариев становятся нулевыми.

Как лучше всего смоделировать такую ​​рекурсивную связь комментариев в DataMapper?


person Tim    schedule 10.12.2010    source источник


Ответы (1)


Что вам нужно, так это самореференциальное соединение в комментариях, например, каждый комментарий может иметь родительский комментарий. Попробуйте следующее:

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 есть плагин вложенных наборов, но я не использовал.

person Joe Harris    schedule 13.01.2011
comment
Только что приступил к тестированию, и он отлично работает - спасибо! - person Tim; 24.02.2011