Моделирование полиморфных постов в блоге - PullRequest
0 голосов
/ 19 мая 2011

Скажем, у меня есть таблица blog_posts. Но пользователи, пишущие сообщения, принадлежат к группам, и у каждой группы есть свой блог.

Например:

Скажем, пользователь принадлежит к 3 группам: Маркетинг, Альфа-проект, Администраторы

Он создает сообщение в блоге, но хочет, чтобы это сообщение появилось в "Маркетинговом блоге" и в блоге "Project Alpha".

Как лучше всего это смоделировать?

Было бы плохой идеей иметь поле в таблице blog_posts, например: group_ids

и сохраните список идентификаторов, разделенных запятыми: 3,7 (где Marketing Group = 3 и Project Alpha = 7)

или я должен создать другую таблицу и сохранить идентификатор и группы blog_posts?

Спасибо.

Ответы [ 3 ]

1 голос
/ 19 мая 2011

Опираясь на ответ @ minitech, у меня будет 3 таблицы моделей и 5 дБ

Модели rails g model <model_name>

  • Пост (должен иметь столбец user_id дляFK)
  • Пользователь
  • Группа

Дополнительные таблицы rails g migration <table_name>

  • groups_posts (столбцы group_id итолько post_id)
  • groups_users (только столбцы group_id и user_id)

Затем в ваших моделях настройте отношения следующим образом

class Post < ActiveRecord::Base
  has_and_belongs_to_many :groups
  belongs_to :user
end

class User < ActiveRecord::Base
  has_and_belongs_to_many :groups
  has_many :posts
end

class Group < ActiveRecord::Base
  has_and_belongs_to_many :users
  has_and_belongs_to_many :posts
end

Затем, согласно вашему примеру,код становится:

user = User.find(<id of user>)
post = Post.create(:title => 'foo', :content => 'bar', :user => user)
post.groups << Group.find(3)
post.groups << Group.find(7)
0 голосов
/ 19 мая 2011

Использование списков, разделенных запятыми, как способ сделать все элементы данных атомарными - плохая идея. Это в основном способ получения данных, которые не находятся в первой нормальной форме, и преобразования, чтобы они выглядели как данные первой нормальной формы, даже если это не так.

Если вы сделаете это, для определенных запросов вам придется выполнить полное сканирование одной из таблиц вместо поиска по индексу. Это будет чудовищно медленно и ухудшаться с увеличением объема данных.

Лучшее решение состоит в том, чтобы иметь соединительную таблицу, которая связывает group_id с user_id.

 Create Table Group_user 
(group_id,
 user_id primary key is (gorup_id,  user_id))

Затем выполните трехстороннее соединение, когда вы хотите собрать все данные вместе. Это основной способ моделирования отношений «многие ко многим».

0 голосов
/ 19 мая 2011

Я бы порекомендовал создать одну таблицу для хранения всех сообщений для всех блогов, затем иметь таблицу для хранения всей информации блогов, а затем таблицу для хранения всех сообщений блогов, на которые ссылается идентификатор. Затем вы просто добавляете, например:

На посты: ID = (значение автоинкремента), Title = 'The title', Content = 'The content'
В записи блога: blogID = (идентификатор блога # 1 , в который нужно вставить сообщение), postID = (значение автоинкремента с прошлого раза)
В записи блога: blogID = (идентификатор блога # 2 , в который нужно вставить сообщение), postID = (значение автоинкремента с прошлого раза)

Таким образом, сообщение связывается, поэтому, когда оно редактируется или удаляется, изменения отражаются во всех блогах, и вы также можете получить быстрый список всех блогов, в которых используется сообщение, что-то вроде SELECT * FROM blogPosts WHERE postID=id_of_post.

...