Commit 568b120b by Rocky Duan

rearranged some code and added feed model

parent c8ad65f4
source :rubygems source :rubygems
gem 'bundler'
gem 'rake' gem 'rake'
gem 'sinatra' gem 'sinatra'
...@@ -17,8 +19,11 @@ gem 'bson_ext' ...@@ -17,8 +19,11 @@ gem 'bson_ext'
gem 'mongoid', "~> 2.4.0" gem 'mongoid', "~> 2.4.0"
gem 'mongoid-tree' gem 'delayed_job'
gem 'voteable_mongo', :git => 'https://github.com/dementrock/voteable_mongo.git' gem 'delayed_job_mongoid'
gem 'mongoid-tree', :git => 'git@github.com:dementrock/mongoid-tree.git', :branch => "mongoid-2.0"
gem 'voteable_mongo', :git => 'git@github.com:dementrock/voteable_mongo.git'
group :test do group :test do
gem 'rspec' gem 'rspec'
......
require 'rubygems' require 'rubygems'
require 'mongo' require 'bundler'
require 'mongoid'
require 'yaml' Bundler.setup
require 'logger' Bundler.require
require 'active_support/all'
require 'sinatra' require './lib/feedstream'
require 'mongoid/tree'
require 'voteable_mongo' require './models/comment.rb'
require './lib/watchable' require './models/comment_thread.rb'
require './lib/followable' require './models/user.rb'
require './models/commentable.rb'
require './models/feed.rb'
desc "Load the environment" desc "Load the environment"
task :environment do task :environment do
...@@ -19,12 +21,18 @@ task :environment do ...@@ -19,12 +21,18 @@ task :environment do
end end
namespace :db do namespace :db do
task :seed => :environment do task :init => :environment do
puts "creating indexes..."
Comment.create_indexes
CommentThread.create_indexes
User.create_indexes
Commentable.create_indexes
Feed.create_indexes
Delayed::Backend::Mongoid::Job.create_indexes
puts "finished"
end
require './models/comment.rb' task :seed => :environment do
require './models/comment_thread.rb'
require './models/user.rb'
require './models/commentable.rb'
Commentable.delete_all Commentable.delete_all
Comment.delete_all Comment.delete_all
......
require 'rubygems' require 'rubygems'
require 'mongo' require 'bundler'
require 'mongoid'
require 'yaml' Bundler.setup
require 'logger' Bundler.require
require 'active_support/all'
require 'sinatra' require './lib/feedstream'
require 'mongoid/tree'
require 'voteable_mongo'
require './lib/followable'
require './lib/watchable'
require './models/comment' require './models/comment'
require './models/comment_thread' require './models/comment_thread'
require './models/commentable' require './models/commentable'
require './models/user' require './models/user'
require './models/feed'
env_index = ARGV.index("-e") env_index = ARGV.index("-e")
env_arg = ARGV[env_index + 1] if env_index env_arg = ARGV[env_index + 1] if env_index
......
require_relative 'feedstream/watchable'
require_relative 'feedstream/watcher'
require_relative 'feedstream/followable'
require_relative 'feedstream/actor'
require_relative 'feedstream/feed'
module Mongoid
module FeedStream
module Actor
extend ActiveSupport::Concern
included do
has_many :activities, class_name: "Feed", inverse_of: :actor, autosave: true
end
end
end
end
module Mongoid
module FeedStream
module Feed
extend ActiveSupport::Concern
included do
include ::Mongoid::Document
include ::Mongoid::Timestamps
field :feed_type, type: String
field :info, type: Hash
belongs_to :actor, class_name: "User", inverse_of: :activities, index: true
belongs_to :target, inverse_of: :activities, polymorphic: true
attr_accessible :feed_type, :info
has_and_belongs_to_many :subscribers, class_name: "User", inverse_of: :feeds
end
end
end
end
module Mongoid module Mongoid
module Followable module FeedStream
extend ActiveSupport::Concern module Followable
extend ActiveSupport::Concern
included do included do
has_and_belongs_to_many :followers, class_name: self.name, inverse_of: :followings has_and_belongs_to_many :followers, class_name: self.name, inverse_of: :followings
has_and_belongs_to_many :followings, class_name: self.name, inverse_of: :followers, autosave: true has_and_belongs_to_many :followings, class_name: self.name, inverse_of: :followers
end end
def follow(user) def follow(user)
if self.id != user.id and not self.following.include? user if self.id != user.id and not self.following.include? user
self.following << user self.following << user
end
end end
end
def unfollow(user) def unfollow(user)
self.following.delete(user) self.following.delete(user)
end
end end
end end
end end
module Mongoid module Mongoid
module Watchable module FeedStream
extend ActiveSupport::Concern module Watchable
included do extend ActiveSupport::Concern
has_and_belongs_to_many :watchers, class_name: "User", inverse_of: "watched_#{self.name.underscore.pluralize}".intern included do
has_and_belongs_to_many :watchers, class_name: "User", inverse_of: "watched_#{self.name.underscore.pluralize}".intern
end
end end
end end
end end
module Mongoid module Mongoid
module Watcher module FeedStream
extend ActiveSupport::Concern module Watcher
extend ActiveSupport::Concern
module ClassMethods included do
def watching(class_plural_sym) has_and_belongs_to_many :feeds, inverse_of: :subscribers
class_plural = class_plural_sym.to_s end
class_single = class_plural.singularize
class_name = class_single.camelize module ClassMethods
watched_symbol = "watched_#{class_plural}".intern def watching(class_plural_sym)
class_plural = class_plural_sym.to_s
class_single = class_plural.singularize
class_name = class_single.camelize
watched_symbol = "watched_#{class_plural}".intern
has_and_belongs_to_many watched_symbol, class_name: class_name, inverse_of: :watchers, autosave: true has_and_belongs_to_many watched_symbol, class_name: class_name, inverse_of: :watchers, autosave: true
self.class_eval <<-END self.class_eval <<-END
def watch_#{class_single}(watching_object) def watch_#{class_single}(watching_object)
if not self.watched_#{class_plural}.include? watching_object if not self.watched_#{class_plural}.include? watching_object
self.watched_#{class_plural} << watching_object self.watched_#{class_plural} << watching_object
end
end end
end
def unwatch_#{class_single}(watching_object) def unwatch_#{class_single}(watching_object)
self.watched_#{class_plural}.delete(watching_object) self.watched_#{class_plural}.delete(watching_object)
end end
END END
end
end end
end end
end end
......
require_relative 'followable/followable'
require_relative 'watchable/watchable'
require_relative 'watchable/watcher'
...@@ -26,34 +26,13 @@ class Comment ...@@ -26,34 +26,13 @@ class Comment
nodes.map{|node, sub_nodes| node.to_hash.merge("children" => hash_tree(sub_nodes).compact)} nodes.map{|node, sub_nodes| node.to_hash.merge("children" => hash_tree(sub_nodes).compact)}
end end
def subtree
arrange(descendants.order_by([[:parent_ids, :asc], [:created_at, :asc]]))
end
def to_hash(params={}) def to_hash(params={})
doc = as_document.slice(*%w[body course_id endorsed _id]).
merge("user_id" => author.external_id).
merge("votes" => votes.slice(*%w[count up_count down_count point]))
if params[:recursive] if params[:recursive]
doc = doc.merge("children" => self.class.hash_tree(subtree)) self.class.hash_tree(subtree(order_by: [[:parent_ids, :asc], [:created_at, :asc]]))
end else
doc as_document.slice(*%w[body course_id endorsed _id]).
end merge("user_id" => author.external_id).
merge("votes" => votes.slice(*%w[count up_count down_count point]))
private
# adopted and modified from https://github.com/stefankroes/ancestry/blob/master/lib/ancestry/class_methods.rb
def arrange(nodes)
# Get all nodes ordered by ancestry and start sorting them into an empty hash
nodes.inject(ActiveSupport::OrderedHash.new) do |arranged_nodes, node|
# Find the insertion point for that node by going through its ancestors
node.parent_ids.inject(arranged_nodes) do |insertion_point, parent_id|
insertion_point.each do |parent, children|
# Change the insertion point to children if node is a descendant of this parent
insertion_point = children if parent_id == parent._id
end
insertion_point
end[node] = ActiveSupport::OrderedHash.new
arranged_nodes
end end
end end
......
...@@ -2,7 +2,7 @@ class CommentThread ...@@ -2,7 +2,7 @@ class CommentThread
include Mongoid::Document include Mongoid::Document
include Mongo::Voteable include Mongo::Voteable
include Mongoid::Timestamps include Mongoid::Timestamps
include Mongoid::Watchable include Mongoid::FeedStream::Watchable
voteable self, :up => +1, :down => -1 voteable self, :up => +1, :down => -1
......
class Commentable class Commentable
include Mongoid::Document include Mongoid::Document
include Mongoid::Watchable include Mongoid::FeedStream::Watchable
field :commentable_type, type: String field :commentable_type, type: String
field :commentable_id, type: String field :commentable_id, type: String
...@@ -13,7 +13,7 @@ class Commentable ...@@ -13,7 +13,7 @@ class Commentable
validates_presence_of :commentable_id validates_presence_of :commentable_id
validates_uniqueness_of :commentable_id, scope: :commentable_type validates_uniqueness_of :commentable_id, scope: :commentable_type
index [:commentable_type, :commentable_id] index [[:commentable_type, Mongo::ASCENDING], [:commentable_id, Mongo::ASCENDING]]
def to_hash def to_hash
as_document as_document
......
class Feed
include Mongoid::FeedStream::Feed
end
class User class User
include Mongoid::Document include Mongoid::Document
include Mongo::Voter include Mongo::Voter
include Mongoid::Watcher include Mongoid::FeedStream::Watcher
include Mongoid::Followable include Mongoid::FeedStream::Actor
include Mongoid::FeedStream::Followable
field :external_id, type: String field :external_id, type: String
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment