mongoid_socializer_actions 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ *.gem
2
+ Gemfile.lock
3
+ .bundle
4
+
5
+ .DS_Store
6
+
7
+ coverage
8
+ rdoc
9
+ pkg
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --colour
3
+ --fail-fast
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use ruby-1.9.3-p125@mongoid_socializer_actions --create
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "http://rubygems.org"
2
+ gemspec
3
+
4
+ gem "rake", "~> 10.0"
5
+
6
+ group :test do
7
+ gem "pry-rails", "~> 0.2.2"
8
+ gem "rspec", "~> 2.12"
9
+ gem 'database_cleaner', "~> 0.9"
10
+ end
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bundler'
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ require 'rspec'
7
+ require 'rspec/core/rake_task'
8
+ RSpec::Core::RakeTask.new(:spec)
9
+
10
+ task :default => [:spec]
11
+
data/Readme.md ADDED
@@ -0,0 +1,73 @@
1
+ # mongoid_socializer_actions
2
+
3
+ mongoid_socializer_actions allows you to easily add liking ability to you Mongoid documents.
4
+
5
+
6
+ ## Installation
7
+
8
+ Add the following to your Gemfile
9
+
10
+ gem 'mongoid_socializer_actions'
11
+
12
+
13
+ ## Requirements
14
+
15
+ This gem has been tested with [MongoID](http://mongoid.org/) version 3.0.21
16
+
17
+
18
+ ## Usage
19
+
20
+ Mongoid Likes provides two modules that you can mix in your model objects like that:
21
+
22
+ class User
23
+ include Mongoid::Document
24
+
25
+ include Mongoid::Liker
26
+ end
27
+
28
+ class Track
29
+ include Mongoid::Document
30
+
31
+ include Mongoid::Likeable
32
+ end
33
+
34
+ You can now like objects like this:
35
+
36
+ user = User.create
37
+ track = Track.create
38
+
39
+ user.like(track)
40
+
41
+ You can query for likes like that:
42
+
43
+ track.all_likers
44
+ # => [user]
45
+
46
+ track.likers_count
47
+ # => 1
48
+
49
+ user.all_likes
50
+ # => [track]
51
+
52
+ Also likes are polymorphic, so let's assume you have a second class `Album` that is including `Mongoid::Likeable` you can do something like this:
53
+
54
+ album = Album.create
55
+ user.like(album)
56
+ user.all_likes
57
+ # => [track, album]
58
+
59
+ user.all_likes_by_model(Album)
60
+ # => [album]
61
+
62
+ user.track_likes_count
63
+ # => 1
64
+
65
+ user.all_track_likes
66
+ # => [track]
67
+
68
+ You get the idea. Have a look at the specs to see some more examples.
69
+
70
+ # TODOs
71
+
72
+ - Implement commentable
73
+ - Implement sharable
@@ -0,0 +1,11 @@
1
+ module Mongoid
2
+ class Like
3
+ include Mongoid::Document
4
+
5
+ # field :like_type
6
+ # field :like_id
7
+
8
+ belongs_to :liker, :class_name => 'User', :inverse_of => :likes
9
+ belongs_to :likable, :polymorphic => true
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ class String
2
+ def camelize
3
+ self.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
4
+ end
5
+ end
@@ -0,0 +1,96 @@
1
+ module Mongoid
2
+ module Likeable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do |base|
6
+ base.field :likers_count, :type => Integer, :default => 0
7
+ base.has_many :likes, :class_name => 'Mongoid::Like', :as => :likable, :dependent => :destroy do
8
+ def liked_by?(model_id)
9
+ where(liker_id: model_id).exists?
10
+ end
11
+ end
12
+ end
13
+
14
+ # know if self is liked by model
15
+ #
16
+ # Example:
17
+ # => @photo.liker?(@john)
18
+ # => true
19
+ def liker?(model)
20
+ self.likers_assoc.liked_by?(model.id)
21
+ end
22
+
23
+ def liked_by?(model)
24
+ self.likes.liked_by?(model.id)
25
+ end
26
+
27
+ # get likers count
28
+ # Note: this is a cache counter
29
+ #
30
+ # Example:
31
+ # => @photo.likers_count
32
+ # => 1
33
+ # def likers_count
34
+ # self.liked_count_field
35
+ # end
36
+
37
+ # get likers count by model
38
+ #
39
+ # Example:
40
+ # => @photo.likers_count_by_model(User)
41
+ # => 1
42
+ def likers_count_by_model(model)
43
+ self.likers_assoc.where(:like_type => model.to_s).count
44
+ end
45
+
46
+ # view all selfs likers
47
+ #
48
+ # Example:
49
+ # => @photo.all_likers
50
+ # => [@john, @jashua]
51
+ def likers
52
+ ids = likes.collect{ |like| like.liker_id }
53
+ ids.present? ? User.find(ids) : []
54
+ end
55
+
56
+ # view all selfs likers by model
57
+ #
58
+ # Example:
59
+ # => @photo.all_likers_by_model
60
+ # => [@john]
61
+ def all_likers_by_model(model)
62
+ get_likers_of(self, model)
63
+ end
64
+
65
+ # view all common likers of self against model
66
+ #
67
+ # Example:
68
+ # => @photo.common_likers_with(@gang)
69
+ # => [@john, @jashua]
70
+ def common_likers_with(model)
71
+ model_likers = get_likers_of(model)
72
+ self_likers = get_likers_of(self)
73
+
74
+ self_likers & model_likers
75
+ end
76
+
77
+ private
78
+ def get_likers_of(me, model = nil)
79
+ likers = !model ? me.likers_assoc : me.likers_assoc.where(:like_type => model.to_s)
80
+
81
+ likers.collect do |like|
82
+ like.like_type.constantize.where(_id: like.like_id).first
83
+ end
84
+ end
85
+
86
+ def method_missing(missing_method, *args, &block)
87
+ if missing_method.to_s =~ /^(.+)_likers_count$/
88
+ likers_count_by_model($1.camelize)
89
+ elsif missing_method.to_s =~ /^all_(.+)_likers$/
90
+ all_likers_by_model($1.camelize)
91
+ else
92
+ super
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,144 @@
1
+ module Mongoid
2
+ module Liker
3
+ extend ActiveSupport::Concern
4
+
5
+ included do |base|
6
+ base.field :likes_count, :type => Integer, :default => 0
7
+ base.has_many :likes, :class_name => 'Mongoid::Like', :inverse_of => :liker, :dependent => :destroy
8
+ end
9
+
10
+ # like a model
11
+ #
12
+ # Example:
13
+ # => @john.like(@photo)
14
+ def like(model)
15
+ unless self.liked?(model)
16
+ model.before_liked_by(self) if model.respond_to?('before_liked_by')
17
+ likes << model.likes.create!
18
+ model.inc(:likers_count, 1)
19
+ model.after_liked_by(self) if model.respond_to?('after_liked_by')
20
+
21
+ self.before_like(model) if self.respond_to?('before_like')
22
+ # self.likes_assoc.create!(:like_type => model.class.name, :like_id => model.id)
23
+ self.inc(:likes_count, 1)
24
+ self.after_like(model) if self.respond_to?('after_like')
25
+ return true
26
+ else
27
+ return false
28
+ end
29
+ end
30
+
31
+ # unlike a model
32
+ #
33
+ # Example:
34
+ # => @john.unlike(@photo)
35
+ def unlike(model)
36
+ if self.id != model.id && self.liked?(model)
37
+
38
+ # this is necessary to handle mongodb caching on collection if unlike is following a like
39
+ model.reload
40
+ self.reload
41
+
42
+ model.before_unliked_by(self) if model.respond_to?('before_unliked_by')
43
+ likes.where(:likable_type => model.class.name, :likable_id => model.id).destroy
44
+ model.inc(:likers_count, -1)
45
+ model.after_unliked_by(self) if model.respond_to?('after_unliked_by')
46
+
47
+ self.before_unlike(model) if self.respond_to?('before_unlike')
48
+ # self.likes_assoc.where(:like_type => model.class.name, :like_id => model.id).destroy
49
+ self.inc(:likes_count, -1)
50
+ self.after_unlike(model) if self.respond_to?('after_unlike')
51
+
52
+ return true
53
+ else
54
+ return false
55
+ end
56
+ end
57
+
58
+ # know if self is already liking model
59
+ #
60
+ # Example:
61
+ # => @john.likes?(@photos)
62
+ # => true
63
+ def liked?(model)
64
+ self.likes.where(likable_id: model.id, likable_type: model.class.to_s).exists?
65
+ end
66
+
67
+ # get likes count
68
+ # Note: this is a cache counter
69
+ #
70
+ # Example:
71
+ # => @john.likes_count
72
+ # => 1
73
+ # def likes_count
74
+ # self.likes_count_field
75
+ # end
76
+
77
+ # get likes count by model
78
+ #
79
+ # Example:
80
+ # => @john.likes_coun_by_model(User)
81
+ # => 1
82
+ def likes_count_by_model(model)
83
+ self.likes_assoc.where(:like_type => model.to_s).count
84
+ end
85
+
86
+ # view all selfs likes
87
+ #
88
+ # Example:
89
+ # => @john.all_likes
90
+ # => [@photo]
91
+ def liked_objects
92
+ get_liked_objects_of_kind
93
+ end
94
+
95
+ # view all selfs likes by model
96
+ #
97
+ # Example:
98
+ # => @john.all_likes_by_model
99
+ # => [@photo]
100
+ def get_liked_objects_of_kind(model = nil)
101
+ if model
102
+ user_likes = likes.where(likable_type: model.class.to_s)
103
+ extract_likes_from(user_likes, model.class.to_s)
104
+ else
105
+ likable_types = likes.map(&:likable_type).uniq
106
+ likable_types.collect do |likable_type|
107
+ user_likes = likes.select{ |like| like.likable_type == likable_type }
108
+ extract_likes_from(user_likes, likable_type)
109
+ end.flatten
110
+ end
111
+ end
112
+
113
+ def extract_likes_from(user_likes, likable_type)
114
+ return [] unless user_likes.present?
115
+ likable_ids = user_likes.map(&:likable_id)
116
+ likable_type.constantize.find(likable_ids)
117
+ end
118
+
119
+ # view all common likes of self against model
120
+ #
121
+ # Example:
122
+ # => @john.common_likes_with(@jashua)
123
+ # => [@photo1, @photo2]
124
+ def common_likes_with(model)
125
+ model_likes = get_likes_of(model)
126
+ self_likes = get_likes_of(self)
127
+
128
+ self_likes & model_likes
129
+ end
130
+
131
+ private
132
+
133
+
134
+ def method_missing(missing_method, *args, &block)
135
+ if missing_method.to_s =~ /^(.+)_likes_count$/
136
+ likes_count_by_model($1.camelize)
137
+ elsif missing_method.to_s =~ /^all_(.+)_likes$/
138
+ all_likes_by_model($1.camelize)
139
+ else
140
+ super
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,5 @@
1
+ module Mongoid
2
+ module MongoidSocializerActions
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ require 'mongoid_socializer_actions/likeable'
2
+ require 'mongoid_socializer_actions/liker'
3
+ require 'mongoid_socializer_actions/helper'
4
+ require 'models/like'
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ # -*- encoding: utf-8 -*-
4
+ $:.push File.expand_path('../lib', __FILE__)
5
+ require 'mongoid_socializer_actions/version'
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = 'mongoid_socializer_actions'
9
+ s.version = Mongoid::MongoidSocializerActions::VERSION
10
+ s.platform = Gem::Platform::RUBY
11
+ s.authors = ['Sreehari B']
12
+ s.email = ['sreehari@activesphere.com']
13
+ s.homepage = 'https://github.com/stigi/mongoid_likes'
14
+ s.summary = %q{Mongoid 3.0 add likable to objects with likers}
15
+ s.description = %q{Add liking ability to Mongoid documents. Qweries are performance optimized}
16
+
17
+ s.add_dependency 'mongoid', '~> 3.0'
18
+ s.add_dependency 'activesupport', '~> 3.2'
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
23
+ s.require_paths = ['lib', 'app']
24
+ end
@@ -0,0 +1,6 @@
1
+ test:
2
+ sessions:
3
+ default:
4
+ database: 'mongoid_socializer_actions_test'
5
+ hosts:
6
+ - localhost:27017
@@ -0,0 +1,4 @@
1
+ class Photo
2
+ include Mongoid::Document
3
+ include Mongoid::Likeable
4
+ end
@@ -0,0 +1,6 @@
1
+ class User
2
+ include Mongoid::Document
3
+ include Mongoid::Liker
4
+
5
+ field :name, type: String
6
+ end
@@ -0,0 +1,91 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe Mongoid::Liker do
4
+ describe User do
5
+ before :each do
6
+ @john = User.create(name: 'john')
7
+ @jashua = User.create(name: 'jashua')
8
+ end
9
+
10
+ it "should have no likes" do
11
+ [@john, @jashua].each {|u| u.liked_objects.should be_empty}
12
+ end
13
+
14
+ describe Photo do
15
+ before :each do
16
+ @photo1 = Photo.create
17
+ @photo2 = Photo.create
18
+ end
19
+
20
+ it "should have no likers" do
21
+ [@photo1, @photo2].each { |t| t.likers.should be_empty }
22
+ end
23
+
24
+ it "should be likeable" do
25
+ expect{ @john.like(@photo1) }.to change(Mongoid::Like, :count).by(1)
26
+ end
27
+
28
+ it "should be liked by liker" do
29
+ @john.like(@photo1)
30
+ @photo1.liked_by?(@john).should be_true
31
+ end
32
+
33
+ it "should not be liked by others" do
34
+ @photo1.liked_by?(@jashua).should_not be_true
35
+ end
36
+
37
+ it "should have the liker as liker" do
38
+ @john.like(@photo1)
39
+ @photo1.likers.should include @john
40
+ end
41
+
42
+ it "should not have others as liker" do
43
+ @photo1.likers.should_not include @jashua
44
+ end
45
+
46
+ it "should be likeable by multiple likers" do
47
+ @jashua.like(@photo1).should be_true
48
+ @john.like(@photo1).should be_true
49
+ end
50
+
51
+ it "should be increase likes_count" do
52
+ expect{ @jashua.like(@photo1) }.to change(@jashua, :likes_count).by(1)
53
+ end
54
+
55
+ it "should be increase likes_count" do
56
+ expect{ @jashua.like(@photo1) }.to change(@photo1, :likers_count).by(1)
57
+ end
58
+
59
+ it "should be liked by multiple likers" do
60
+ @jashua.like(@photo1)
61
+ @john.like(@photo1)
62
+ @photo1.likers.should include @john, @jashua
63
+ end
64
+
65
+ it "should have the correct likers count" do
66
+ @jashua.like(@photo1)
67
+ @john.like(@photo1)
68
+ @photo1.likers_count.should be 2
69
+ @jashua.likes_count.should be 1
70
+ @john.likes_count.should be 1
71
+ end
72
+
73
+ it "should be unlikable" do
74
+ @jashua.like(@photo1)
75
+ @jashua.unlike(@photo1).should be_true
76
+ end
77
+
78
+ it "should not be unlikable by unliker" do
79
+ @jashua.unlike(@photo1).should be_false
80
+ end
81
+
82
+ it "should not include former liker" do
83
+ @photo1.likers.should_not include @jashua
84
+ end
85
+
86
+ it "should not be included in former likes" do
87
+ @jashua.liked_objects.should_not include @photo1
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,41 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup
4
+
5
+ require 'mongoid'
6
+ require 'database_cleaner'
7
+
8
+ models_folder = File.join(File.dirname(__FILE__), 'mongoid/models')
9
+
10
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
11
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
12
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'app'))
13
+
14
+ Mongoid.load! '/Users/sreehari/MyProjects/mongoid_likes/spec/config/mongoid.yml', :test
15
+
16
+ require 'mongoid_socializer_actions'
17
+ require 'rspec'
18
+ require 'rspec/autorun'
19
+ require 'pry-rails'
20
+
21
+ Dir[ File.join(models_folder, '*.rb') ].each { |file|
22
+ require file
23
+ file_name = File.basename(file).sub('.rb', '')
24
+ klass = file_name.classify.constantize
25
+ klass.collection.drop
26
+ }
27
+
28
+ RSpec.configure do |config|
29
+ config.before(:suite) do
30
+ DatabaseCleaner.strategy = :truncation
31
+ DatabaseCleaner.clean_with(:truncation)
32
+ end
33
+
34
+ config.before(:each) do
35
+ DatabaseCleaner.start
36
+ end
37
+
38
+ config.after(:each) do
39
+ DatabaseCleaner.clean
40
+ end
41
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongoid_socializer_actions
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Sreehari B
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-08 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mongoid
16
+ requirement: &2152186160 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2152186160
25
+ - !ruby/object:Gem::Dependency
26
+ name: activesupport
27
+ requirement: &2152185660 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: '3.2'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *2152185660
36
+ description: Add liking ability to Mongoid documents. Qweries are performance optimized
37
+ email:
38
+ - sreehari@activesphere.com
39
+ executables: []
40
+ extensions: []
41
+ extra_rdoc_files: []
42
+ files:
43
+ - .gitignore
44
+ - .rspec
45
+ - .rvmrc
46
+ - Gemfile
47
+ - Rakefile
48
+ - Readme.md
49
+ - app/models/like.rb
50
+ - lib/mongoid_socializer_actions.rb
51
+ - lib/mongoid_socializer_actions/helper.rb
52
+ - lib/mongoid_socializer_actions/likeable.rb
53
+ - lib/mongoid_socializer_actions/liker.rb
54
+ - lib/mongoid_socializer_actions/version.rb
55
+ - mongoid_socializer_actions.gemspec
56
+ - spec/config/mongoid.yml
57
+ - spec/mongoid/models/photo.rb
58
+ - spec/mongoid/models/user.rb
59
+ - spec/mongoid/mongoid_socializer_actions/likes_spec.rb
60
+ - spec/spec_helper.rb
61
+ homepage: https://github.com/stigi/mongoid_likes
62
+ licenses: []
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ - app
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ requirements: []
81
+ rubyforge_project:
82
+ rubygems_version: 1.8.10
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: Mongoid 3.0 add likable to objects with likers
86
+ test_files:
87
+ - spec/config/mongoid.yml
88
+ - spec/mongoid/models/photo.rb
89
+ - spec/mongoid/models/user.rb
90
+ - spec/mongoid/mongoid_socializer_actions/likes_spec.rb
91
+ - spec/spec_helper.rb