Как лучше всего добавлять комментарии ко многим моделям? - PullRequest
4 голосов
/ 07 марта 2009

Hi Stack Overflowers: я создаю приложение Ruby on Rails, которое имеет несколько разных моделей (например, фильмы, песни, фото), в которых я храню фрагменты фильмов, mp3-файлы и фотографии. Я бы хотел, чтобы пользователи могли комментировать любую из этих моделей и контролировать, какие комментарии публикуются.

Лучше всего создавать модель комментариев с помощью:

belongs_to :movie
belongs_to :song
belongs_to :photo

А затем свяжите каждую модель с:

has_many :comments

Тогда, я думаю, в таблице комментариев мне понадобится внешний ключ для каждой модели:

comment, movie_id, song_id, photo_id

Это правильный способ построить что-то подобное или есть лучший способ? Заранее благодарим за помощь.

Ответы [ 5 ]

4 голосов
/ 07 марта 2009

Использование acts_as_commentable. Создается таблица комментариев с commentable_type (название модели элемента с комментариями) и commentable_id (идентификатор модели) Тогда все что вам нужно сделать в ваших моделях:

class Photo < ActiveRecord::Base
  acts_as_commentable
end
1 голос
/ 08 марта 2009

Лично я бы смоделировал это так:

Media table (media_id, type_id, content, ...)
.
MediaType table (type_id, description, ... )
.
MediaComments table ( comment_id, media_id, comment_text, ...)

В конце концов, нет никакой разницы в базе данных между песней, фильмом или фотографией. Это все только двоичные данные. С этой моделью вы можете добавлять новые «типы носителей» без перекодирования. Добавьте новую запись «MediaType» и добавьте данные в таблицу «Media».

Так гораздо гибче.

1 голос
/ 07 марта 2009

Создайте таблицу для хранения связей для каждого типа комментариев:

movie_comments, song_comments, photo_comments

и затем используйте:

class Movie < ActiveRecord::Base

  has_many :movie_comments
  has_many :comments, :through => :movie_comments

end

class MovieComment < ActiveRecord::Base
  include CommentRelationship
  belongs_to :comment
  belongs_to :movie
end

Вы можете использовать модуль (CommentRelationship) для хранения всех общих функций между вашими таблицами отношений (movie_comments)

Этот подход обеспечивает гибкость, позволяющую обрабатывать ваши комментарии по-разному в зависимости от типа, в то же время допуская одинаковую функциональность между ними. Кроме того, вы не получите тонны пустых записей в каждом столбце:

comment            | movie_id | photo_id | song_id
----------------------------------------------------
Some comment            10         null      null
Some other comment     null        23        null

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

0 голосов
/ 08 марта 2009

Лучшая идея, вероятно, сделать то, что предлагает Сара, и использовать один из существующих плагинов, которые обрабатывают комментарии.

Если вы хотите свернуть свое собственное дело или просто понять, что происходит под прикрытием, вам нужно прочитать о наследовании отдельных таблиц, как Rails обрабатывает наследование. По сути, вам нужен один comments стол ala:

# db/migrate/xxx_create_comments
create_table :comments do |t|
  t.string :type, :null => false
  t.references :movies, :songs, :photos
end

Теперь вы можете определять типы комментариев как

class Comment < ActiveRecord::Base
  validates_presence_of :body, :author
  # shared validations go here
end

class SongComment < Comment
  belongs_to :song
end

class MovieComment < Comment
  belongs_to :movie
end

class PhotoComment < Comment
  belongs_to :photo
end

Все ваши комментарии будут храниться в одной таблице comments, но PhotoComment.all возвращает только те комментарии, для которых type == "Photo".

0 голосов
/ 07 марта 2009

У меня нет опыта RoR, но в этом случае вам, вероятно, лучше использовать наследование на уровне базы данных, если ваша база данных поддерживает это:

CREATE TABLE item (int id, ...);
CREATE TABLE movie (...) INHERITS (item);
CREATE TABLE song (...) INHERITS (item);
[...]
CREATE TABLE comments (int id, int item_id REFERENCES item(id));

Другим подходом может быть одна таблица со столбцом типа:

CREATE TABLE item (int id, int type...);
CREATE TABLE comments (int id, int item_id REFERENCES item(id));

Как уже было сказано, я не могу сказать вам, как именно реализовать это с помощью RoR.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...