mongoid_likes 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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/.rbenv-gemsets ADDED
@@ -0,0 +1 @@
1
+ mongoid_likes
data/.rbenv-version ADDED
@@ -0,0 +1 @@
1
+ 1.9.2-p290
data/.rvmrc ADDED
@@ -0,0 +1,2 @@
1
+ rvm_gemset_create_on_use_flag=1
2
+ rvm use 1.9.2@mongoid_likes
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
data/.watchr ADDED
@@ -0,0 +1,23 @@
1
+ # vim:set filetype=ruby:
2
+ def run(cmd)
3
+ puts cmd
4
+ system cmd
5
+ end
6
+
7
+ def spec(file)
8
+ if File.exists?(file)
9
+ run("rspec #{file}")
10
+ else
11
+ puts("Spec: #{file} does not exist.")
12
+ end
13
+ end
14
+
15
+ watch("spec/.*/*_spec\.rb") do |match|
16
+ puts(match[0])
17
+ spec(match[0])
18
+ end
19
+
20
+ watch("lib/(.*/.*)\.rb") do |match|
21
+ puts(match[1])
22
+ spec("spec/#{match[1]}_spec.rb")
23
+ end
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "http://rubygems.org"
2
+
3
+ group :test do
4
+ gem 'rake'
5
+ end
6
+ # Specify your gem's dependencies in mongoid_likes.gemspec
7
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec'
5
+ require 'rspec/core/rake_task'
6
+ RSpec::Core::RakeTask.new(:spec) do |spec|
7
+ spec.pattern = 'spec/**/*_spec.rb'
8
+ end
9
+
10
+ task :default => ['spec']
data/Readme.md ADDED
@@ -0,0 +1,78 @@
1
+ # Mongoid Likes
2
+
3
+ mongoid_likes allows you to easily add liking ability to you Mongoid documents.
4
+
5
+ [![Build Status](https://secure.travis-ci.org/stigi/mongoid_likes.png?branch=master)](http://travis-ci.org/stigi/mongoid_likes)
6
+
7
+ ## Installation
8
+
9
+ Add the following to your Gemfile
10
+
11
+ gem 'mongoid_follow'
12
+
13
+ If you like living on the edge (or if this gem isn't yet available on rubygems) you can add
14
+
15
+ gem 'mongoid_likes', :git => 'git://github.com/stigi/mongoid_likes.git', :branch => 'development'
16
+
17
+
18
+ ## Requirements
19
+
20
+ This gem has been tested with [MongoID](http://mongoid.org/) version 2.4.7.
21
+
22
+
23
+ ## Usage
24
+
25
+ Mongoid Likes provides two modules that you can mix in your model objects like that:
26
+
27
+ class User
28
+ include Mongoid::Document
29
+
30
+ include Mongoid::Liker
31
+ end
32
+
33
+ class Track
34
+ include Mongoid::Document
35
+
36
+ include Mongoid::Likeable
37
+ end
38
+
39
+ You can now like objects like this:
40
+
41
+ user = User.create
42
+ track = Track.create
43
+
44
+ user.like(track)
45
+
46
+ You can query for likes like that:
47
+
48
+ track.all_likers
49
+ # => [user]
50
+
51
+ track.likers_count
52
+ # => 1
53
+
54
+ user.all_likes
55
+ # => [track]
56
+
57
+ 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:
58
+
59
+ album = Album.create
60
+ user.like(album)
61
+ user.all_likes
62
+ # => [track, album]
63
+
64
+ user.all_likes_by_model(Album)
65
+ # => [album]
66
+
67
+ user.track_likes_count
68
+ # => 1
69
+
70
+ user.all_track_likes
71
+ # => [track]
72
+
73
+ You get the idea. Have a look at the specs to see some more examples.
74
+
75
+ # TODOs
76
+
77
+ - write a proper readme
78
+ - generate some documentation
@@ -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, :polymorphic => true
9
+ belongs_to :liked, :polymorphic => true
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ require 'mongoid_likes/likeable'
2
+ require 'mongoid_likes/liker'
3
+ require 'mongoid_likes/helper'
4
+ require 'models/mongoid_likes/like'
@@ -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,87 @@
1
+ module Mongoid
2
+ module Likeable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do |base|
6
+ base.field :liked_count_field, :type => Integer, :default => 0
7
+ base.has_many :likers_assoc, :class_name => 'Mongoid::Like', :as => :liked, :dependent => :destroy
8
+ end
9
+
10
+ # know if self is liked by model
11
+ #
12
+ # Example:
13
+ # => @track.liker?(@joe)
14
+ # => true
15
+ def liker?(model)
16
+ self.likers_assoc.find(:all, conditions: {like_id: model.id}).limit(1).count > 0
17
+ end
18
+
19
+ # get likers count
20
+ # Note: this is a cache counter
21
+ #
22
+ # Example:
23
+ # => @track.likers_count
24
+ # => 1
25
+ def likers_count
26
+ self.liked_count_field
27
+ end
28
+
29
+ # get likers count by model
30
+ #
31
+ # Example:
32
+ # => @track.likers_count_by_model(User)
33
+ # => 1
34
+ def likers_count_by_model(model)
35
+ self.likers_assoc.where(:like_type => model.to_s).count
36
+ end
37
+
38
+ # view all selfs likers
39
+ #
40
+ # Example:
41
+ # => @track.all_likers
42
+ # => [@joe, @max]
43
+ def all_likers
44
+ get_likers_of(self)
45
+ end
46
+
47
+ # view all selfs likers by model
48
+ #
49
+ # Example:
50
+ # => @track.all_likers_by_model
51
+ # => [@joe]
52
+ def all_likers_by_model(model)
53
+ get_likers_of(self, model)
54
+ end
55
+
56
+ # view all common likers of self against model
57
+ #
58
+ # Example:
59
+ # => @track.common_likers_with(@gang)
60
+ # => [@joe, @max]
61
+ def common_likers_with(model)
62
+ model_likers = get_likers_of(model)
63
+ self_likers = get_likers_of(self)
64
+
65
+ self_likers & model_likers
66
+ end
67
+
68
+ private
69
+ def get_likers_of(me, model = nil)
70
+ likers = !model ? me.likers_assoc : me.likers_assoc.where(:like_type => model.to_s)
71
+
72
+ likers.collect do |like|
73
+ like.like_type.constantize.find(like.like_id)
74
+ end
75
+ end
76
+
77
+ def method_missing(missing_method, *args, &block)
78
+ if missing_method.to_s =~ /^(.+)_likers_count$/
79
+ likers_count_by_model($1.camelize)
80
+ elsif missing_method.to_s =~ /^all_(.+)_likers$/
81
+ all_likers_by_model($1.camelize)
82
+ else
83
+ super
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,137 @@
1
+ module Mongoid
2
+ module Liker
3
+ extend ActiveSupport::Concern
4
+
5
+ included do |base|
6
+ base.field :likes_count_field, :type => Integer, :default => 0
7
+ base.has_many :likes_assoc, :class_name => 'Mongoid::Like', :as => :liker, :dependent => :destroy
8
+ end
9
+
10
+ # like a model
11
+ #
12
+ # Example:
13
+ # => @joe.like(@track)
14
+ def like(model)
15
+ if self.id != model.id && !self.likes?(model)
16
+
17
+ model.before_liked_by(self) if model.respond_to?('before_liked_by')
18
+ model.likers_assoc.create!(:like_type => self.class.name, :like_id => self.id)
19
+ model.inc(:liked_count_field, 1)
20
+ model.after_liked_by(self) if model.respond_to?('after_liked_by')
21
+
22
+ self.before_like(model) if self.respond_to?('before_like')
23
+ self.likes_assoc.create!(:like_type => model.class.name, :like_id => model.id)
24
+ self.inc(:likes_count_field, 1)
25
+ self.after_like(model) if self.respond_to?('after_like')
26
+
27
+ return true
28
+ else
29
+ return false
30
+ end
31
+ end
32
+
33
+ # unlike a model
34
+ #
35
+ # Example:
36
+ # => @joe.unlike(@track)
37
+ def unlike(model)
38
+ if self.id != model.id && self.likes?(model)
39
+
40
+ # this is necessary to handle mongodb caching on collection if unlike is following a like
41
+ model.reload
42
+ self.reload
43
+
44
+ model.before_unliked_by(self) if model.respond_to?('before_unliked_by')
45
+ model.likers_assoc.where(:like_type => self.class.name, :like_id => self.id).destroy
46
+ model.inc(:liked_count_field, -1)
47
+ model.after_unliked_by(self) if model.respond_to?('after_unliked_by')
48
+
49
+ self.before_unlike(model) if self.respond_to?('before_unlike')
50
+ self.likes_assoc.where(:like_type => model.class.name, :like_id => model.id).destroy
51
+ self.inc(:likes_count_field, -1)
52
+ self.after_unlike(model) if self.respond_to?('after_unlike')
53
+
54
+ return true
55
+ else
56
+ return false
57
+ end
58
+ end
59
+
60
+ # know if self is already liking model
61
+ #
62
+ # Example:
63
+ # => @joe.likes?(@tracks)
64
+ # => true
65
+ def likes?(model)
66
+ self.likes_assoc.find(:all, conditions: {like_id: model.id}).limit(1).count > 0
67
+ end
68
+
69
+ # get likes count
70
+ # Note: this is a cache counter
71
+ #
72
+ # Example:
73
+ # => @joe.likes_count
74
+ # => 1
75
+ def likes_count
76
+ self.likes_count_field
77
+ end
78
+
79
+ # get likes count by model
80
+ #
81
+ # Example:
82
+ # => @joe.likes_coun_by_model(User)
83
+ # => 1
84
+ def likes_count_by_model(model)
85
+ self.likes_assoc.where(:like_type => model.to_s).count
86
+ end
87
+
88
+ # view all selfs likes
89
+ #
90
+ # Example:
91
+ # => @joe.all_likes
92
+ # => [@track]
93
+ def all_likes
94
+ get_likes_of(self)
95
+ end
96
+
97
+ # view all selfs likes by model
98
+ #
99
+ # Example:
100
+ # => @joe.all_likes_by_model
101
+ # => [@track]
102
+ def all_likes_by_model(model)
103
+ get_likes_of(self, model)
104
+ end
105
+
106
+ # view all common likes of self against model
107
+ #
108
+ # Example:
109
+ # => @joe.common_likes_with(@max)
110
+ # => [@track1, @track2]
111
+ def common_likes_with(model)
112
+ model_likes = get_likes_of(model)
113
+ self_likes = get_likes_of(self)
114
+
115
+ self_likes & model_likes
116
+ end
117
+
118
+ private
119
+ def get_likes_of(me, model = nil)
120
+ likes = !model ? me.likes_assoc : me.likes_assoc.where(:like_type => model.to_s)
121
+
122
+ likes.collect do |like|
123
+ like.like_type.constantize.find(like.like_id)
124
+ end
125
+ end
126
+
127
+ def method_missing(missing_method, *args, &block)
128
+ if missing_method.to_s =~ /^(.+)_likes_count$/
129
+ likes_count_by_model($1.camelize)
130
+ elsif missing_method.to_s =~ /^all_(.+)_likes$/
131
+ all_likes_by_model($1.camelize)
132
+ else
133
+ super
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,5 @@
1
+ module Mongoid
2
+ module Likes
3
+ VERSION = '0.0.1'
4
+ end
5
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'mongoid_likes/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'mongoid_likes'
7
+ s.version = Mongoid::Likes::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ['Ullrich Schäfer']
10
+ s.email = ['ullrich@seidbereit.de']
11
+ s.homepage = 'https://github.com/stigi/mongoid_likes'
12
+ s.summary = %q{Add likeing ability to Mongoid documents}
13
+ s.description = %q{Add liking ability to Mongoid documents. Also adds the inverse relation}
14
+
15
+ s.add_development_dependency 'rspec', '~> 2.5'
16
+ s.add_development_dependency 'mongoid', '~> 2.0'
17
+ s.add_development_dependency 'bson_ext', '~> 1.4'
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.require_paths = ['lib']
23
+ end
@@ -0,0 +1,4 @@
1
+ class Track
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,71 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+
3
+ describe Mongoid::Likes do
4
+ describe User do
5
+ before :all do
6
+ @joe = User.create(name: 'Joe')
7
+ @max = User.create(name: 'Max')
8
+ end
9
+
10
+ it "should have no likes" do
11
+ [@joe, @max].each {|u| u.all_likes.should be_empty}
12
+ end
13
+
14
+ describe Track do
15
+ before :all do
16
+ @track1 = Track.create
17
+ @track2 = Track.create
18
+ end
19
+
20
+ it "should have no likers" do
21
+ [@track1, @track2].each { |t| t.all_likers.should be_empty }
22
+ end
23
+
24
+ it "should be likeable" do
25
+ @joe.like(@track1)
26
+ end
27
+
28
+ it "should be liked by liker" do
29
+ @track1.liker?(@joe).should be_true
30
+ end
31
+
32
+ it "should not be liked by others" do
33
+ @track1.liker?(@max).should_not be_true
34
+ end
35
+
36
+ it "should have the liker as liker" do
37
+ @track1.all_likers.should include @joe
38
+ end
39
+
40
+ it "should not have others as liker" do
41
+ @track1.all_likers.should_not include @max
42
+ end
43
+
44
+ it "should be likeable by multiple likers" do
45
+ @max.like(@track1)
46
+ end
47
+
48
+ it "should be liked by multiple likers" do
49
+ @track1.all_likers.should include @joe, @max
50
+ end
51
+
52
+ it "should have the correct likers count" do
53
+ @track1.likers_count.should be 2
54
+ @max.likes_count.should be 1
55
+ @joe.likes_count.should be 1
56
+ end
57
+
58
+ it "should be unlikable" do
59
+ @max.unlike(@track1)
60
+ end
61
+
62
+ it "should not include former liker" do
63
+ @track1.all_likers.should_not include @max
64
+ end
65
+
66
+ it "should not be included in former likes" do
67
+ @max.all_likes.should_not include @track1
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,29 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup
4
+
5
+
6
+ require 'mongoid'
7
+ models_folder = File.join(File.dirname(__FILE__), 'mongoid/models')
8
+ Mongoid.configure do |config|
9
+ name = 'mongoid_likes_test'
10
+ host = 'localhost'
11
+ config.master = Mongo::Connection.new.db(name)
12
+ config.autocreate_indexes = true
13
+ end
14
+
15
+
16
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
17
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
18
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'app'))
19
+
20
+ require 'mongoid_likes'
21
+ require 'rspec'
22
+ require 'rspec/autorun'
23
+
24
+ Dir[ File.join(models_folder, '*.rb') ].each { |file|
25
+ require file
26
+ file_name = File.basename(file).sub('.rb', '')
27
+ klass = file_name.classify.constantize
28
+ klass.collection.drop
29
+ }
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongoid_likes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ullrich Schäfer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.5'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '2.5'
30
+ - !ruby/object:Gem::Dependency
31
+ name: mongoid
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '2.0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '2.0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: bson_ext
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '1.4'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '1.4'
62
+ description: Add liking ability to Mongoid documents. Also adds the inverse relation
63
+ email:
64
+ - ullrich@seidbereit.de
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files: []
68
+ files:
69
+ - .gitignore
70
+ - .rbenv-gemsets
71
+ - .rbenv-version
72
+ - .rvmrc
73
+ - .travis.yml
74
+ - .watchr
75
+ - Gemfile
76
+ - Rakefile
77
+ - Readme.md
78
+ - app/models/mongoid_likes/like.rb
79
+ - lib/mongoid_likes.rb
80
+ - lib/mongoid_likes/helper.rb
81
+ - lib/mongoid_likes/likeable.rb
82
+ - lib/mongoid_likes/liker.rb
83
+ - lib/mongoid_likes/version.rb
84
+ - mongoid_likes.gemspec
85
+ - spec/mongoid/models/track.rb
86
+ - spec/mongoid/models/user.rb
87
+ - spec/mongoid/mongoid_likes/likes_spec.rb
88
+ - spec/spec_helper.rb
89
+ homepage: https://github.com/stigi/mongoid_likes
90
+ licenses: []
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ! '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 1.8.21
110
+ signing_key:
111
+ specification_version: 3
112
+ summary: Add likeing ability to Mongoid documents
113
+ test_files:
114
+ - spec/mongoid/models/track.rb
115
+ - spec/mongoid/models/user.rb
116
+ - spec/mongoid/mongoid_likes/likes_spec.rb
117
+ - spec/spec_helper.rb