Rails: стоит ли использовать STI?

Я хочу представить свое дело и узнать, следует ли мне использовать решение STI.
Я создаю веб-сайт доски объявлений, и пока у меня есть несколько моделей: пользователь, тема, сообщение..
чтобы было ясно: сообщение похоже на комментарий к теме. Тема имеет название и содержание. Пост имеет только содержание.

Теперь у Пользователя есть возможность Нравится/Не нравится Сообщению или Теме. Я думал о трех вариантах:

  1. Тема и сообщение не связаны (у каждой модели есть «количество_лайков», «количество_дизлайков»)
  2. Тема наследует сообщение.
  3. Тема и сообщение наследуются от базовой модели, которую можно назвать, например, LikeableObj.

Какой из этих трех вариантов больше всего подходит для моих нужд?
Есть ли четвертый вариант, о котором я не подумал?
Что делать, если в будущем я хотел бы иметь третью Модель, которая может быть Понравилось?


person socksocket    schedule 14.12.2012    source источник


Ответы (1)


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

class Like < ActiveRecord::Base
  belongs_to :user
  belongs_to :liked_obj, polymorphic:true, counter_cache:true
end

Поскольку Like_obj полиморфен, это может быть пост или тема. Затем вы можете поместить has_many :likes в эти модели и столбец likes_count, который будет автоматически обновляться как кэш-счетчик.

Если у вас есть какой-либо код, который работает с лайками, общий для Post и Topic, поместите его в module Likeable и включите в оба класса.

person mckeed    schedule 14.12.2012
comment
Вы предлагаете создать likes_controller для обработки подобных запросов? - person socksocket; 15.12.2012
comment
Это своего рода вопрос стиля. Likes_controller был бы способом RESTful, который обычно предпочтительнее в наши дни, но я предпочитаю старый способ rails, просто добавляющий метод like к контроллерам сообщений и тем. (В этом случае это должен быть PUT.) - person mckeed; 17.12.2012