Было бы лучше использовать первый подход (отдельные документы) и использовать ограниченную коллекцию, если это возможно, так как вы не хотите иметь быстро растущую коллекцию (mongoid будет иметь поддержку ограниченных коллекций в версии 2.2, которая будет отсутствовать в эти выходные я думаю).
При втором подходе (внедренные документы) вам необходимо сначала получить корневой документ для пользователя, а затем просмотреть массив в приложении, чтобы найти действие, связанное с публикацией, которую вы ищете. Mongoid может заставить его выглядеть так, как будто все делается в БД, из-за сходства синтаксиса при поиске внедренного документа, но на самом деле он повторяет массив.
Поскольку у вас уже есть user_id, activity_id и activity_type до выполнения запроса, и вы не хотите, чтобы весь список действий для пользователя был извлечен из базы данных, когда вы ищете конкретное действие, я предпочту первый случай , В приложении будет намного меньше вычислений (поиска) и будет намного меньше сетевого трафика.
При подходе к отдельным документам было бы замечательно, если бы вы также создали уникальный индекс для user_id, activity_id, activity_type. Это поможет вам содержать количество документов. Вы можете провести проверку уникальности (дополнительный запрос), но это будет в основном ненужным, если у вас есть уникальный индекс. Единственным преимуществом проверки будет ошибка проверки, если есть дубликаты, но индекс будет игнорировать повторяющиеся записи в автоматическом режиме, если вы не сохраните его в безопасном режиме.
Если вы также хотите, чтобы историческая активность сайта сохранялась, вы можете иметь такую структуру:
class SiteActivity
include Mongoid::Document
include Mongoid::Timestamps
belongs_to :user
belongs_to :activity, polymorphic: true
index [:user_id, :activity_id, :activity_type], :background => true, :unique => true
field :last_access_time, :type => Time
# last_access_times just here for history, not used
field :last_access_times, :type => Array, :default => []
end
activity = SiteActivity.find_or_initialize_by(:user_id => current_user.id,
:activity_id => post.id, :activity_type => post.class)
time = Time.now.utc
activity.last_access_time = time
activity.last_access_times << time
activity.save