like_system 0.0.6

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.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/.empty +0 -0
  3. data/.gitignore +15 -0
  4. data/.keep +0 -0
  5. data/.rspec +2 -0
  6. data/.ruby-gemset +1 -0
  7. data/.ruby-version +1 -0
  8. data/.travis.yml +23 -0
  9. data/Appraisals +7 -0
  10. data/Gemfile +4 -0
  11. data/LICENSE.txt +22 -0
  12. data/README.md +93 -0
  13. data/Rakefile +8 -0
  14. data/gemfiles/.empty +0 -0
  15. data/gemfiles/.gitignore +0 -0
  16. data/gemfiles/.keep +0 -0
  17. data/gemfiles/rails4.1.gemfile +7 -0
  18. data/gemfiles/rails4.2.gemfile +7 -0
  19. data/lib/.empty +0 -0
  20. data/lib/.gitignore +0 -0
  21. data/lib/.keep +0 -0
  22. data/lib/generators/.empty +0 -0
  23. data/lib/generators/.gitignore +0 -0
  24. data/lib/generators/.keep +0 -0
  25. data/lib/generators/like_system/.empty +0 -0
  26. data/lib/generators/like_system/.gitignore +0 -0
  27. data/lib/generators/like_system/.keep +0 -0
  28. data/lib/generators/like_system/like_system_generator.rb +46 -0
  29. data/lib/generators/like_system/templates/.empty +0 -0
  30. data/lib/generators/like_system/templates/.gitignore +0 -0
  31. data/lib/generators/like_system/templates/.keep +0 -0
  32. data/lib/generators/like_system/templates/migration.rb +47 -0
  33. data/lib/like_system.rb +45 -0
  34. data/lib/like_system/.empty +0 -0
  35. data/lib/like_system/.gitignore +0 -0
  36. data/lib/like_system/.keep +0 -0
  37. data/lib/like_system/like.rb +155 -0
  38. data/lib/like_system/likee.rb +58 -0
  39. data/lib/like_system/liker.rb +88 -0
  40. data/lib/like_system/version.rb +12 -0
  41. data/like_system.gemspec +31 -0
  42. data/spec/.empty +0 -0
  43. data/spec/.gitignore +0 -0
  44. data/spec/.keep +0 -0
  45. data/spec/db/.empty +0 -0
  46. data/spec/db/.gitignore +0 -0
  47. data/spec/db/.keep +0 -0
  48. data/spec/db/migrate/.empty +0 -0
  49. data/spec/db/migrate/.gitignore +0 -0
  50. data/spec/db/migrate/.keep +0 -0
  51. data/spec/db/migrate/20140926000000_create_likes.rb +47 -0
  52. data/spec/db/migrate/20140926000005_create_dummy_likers.rb +22 -0
  53. data/spec/db/migrate/20140926000010_create_dummy_likees.rb +22 -0
  54. data/spec/like_system/.empty +0 -0
  55. data/spec/like_system/.gitignore +0 -0
  56. data/spec/like_system/.keep +0 -0
  57. data/spec/like_system/like_spec.rb +177 -0
  58. data/spec/like_system/likee_spec.rb +69 -0
  59. data/spec/like_system/liker_spec.rb +96 -0
  60. data/spec/spec_helper.rb +116 -0
  61. data/spec/support/.empty +0 -0
  62. data/spec/support/.gitignore +0 -0
  63. data/spec/support/.keep +0 -0
  64. data/spec/support/active_record.rb +12 -0
  65. data/spec/support/shoulda_matchers.rb +2 -0
  66. metadata +237 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b3168bfa085ef7fa2e484644fc12c8179695c15b
4
+ data.tar.gz: 8dc6b2f9eeb7a65e21ff138144f91603f109035e
5
+ SHA512:
6
+ metadata.gz: 46e84bd220a8d5f0c5668a623fba58d68749a092a89a08c6d629b1276e284994d94da097e7f96d5bc9508985b2b3eda44de8ed4f1cce5819d4832b72dd2d3b1f
7
+ data.tar.gz: 2920dcd80fe68f965c7dc2646d3ea7ee90d426ece10226cabe61e9939614a66f1c33adebeba8fa3b5fb20b2b918c33a315f625fc97616bbb3678a530a290a717
data/.empty ADDED
File without changes
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /gemfiles/*.lock
8
+ /pkg/
9
+ /spec/reports/
10
+ /tmp/
11
+ *.bundle
12
+ *.so
13
+ *.o
14
+ *.a
15
+ mkmf.log
data/.keep ADDED
File without changes
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ like_system
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.2.1
data/.travis.yml ADDED
@@ -0,0 +1,23 @@
1
+ language:
2
+ - ruby
3
+
4
+ rvm:
5
+ - 2.0.0
6
+ - 2.1.3
7
+ - 2.2.1
8
+
9
+ gemfile:
10
+ - gemfiles/rails4.1.gemfile
11
+ - gemfiles/rails4.2.gemfile
12
+
13
+ install:
14
+ - "travis_retry bundle install"
15
+
16
+ before_script:
17
+
18
+ script:
19
+ - "bundle exec rake"
20
+
21
+ branches:
22
+ only:
23
+ - master
data/Appraisals ADDED
@@ -0,0 +1,7 @@
1
+ appraise "rails4.1" do
2
+ gem "rails", "4.1.10"
3
+ end
4
+
5
+ appraise "rails4.2" do
6
+ gem "rails", "4.2.1"
7
+ end
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in like_system.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Pablo Martin Viva
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # LikeSystem
2
+
3
+ [![Build Status](https://travis-ci.org/pmviva/like_system.png?branch=master)](https://travis-ci.org/pmviva/like_system)
4
+ [![Gem Version](https://badge.fury.io/rb/like_system.svg)](http://badge.fury.io/rb/like_system)
5
+
6
+ An active record like system developed using ruby on rails 4.1 applying domain driven design and test driven development principles.
7
+
8
+ This gem is heavily influenced by cmer/socialization.
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ ```ruby
15
+ gem 'like_system'
16
+ ```
17
+
18
+ And then execute:
19
+
20
+ ```ruby
21
+ $ bundle
22
+ ```
23
+
24
+ Or install it yourself as:
25
+
26
+ ```ruby
27
+ $ gem install like_system
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ ### Run the generator
33
+
34
+ ```ruby
35
+ $ rails g like_system
36
+ ```
37
+
38
+ Let's suppose for a moment that you have a blog application and a User can like a Post or several Post models.
39
+ The user model becomes the liker and the post model becomes the likee.
40
+
41
+ ### Post object
42
+ ```ruby
43
+ class Post < ActiveRecord::Base
44
+ act_as_likee
45
+
46
+ validates :content, presence: true
47
+ end
48
+ ```
49
+
50
+ ### User object
51
+ ```ruby
52
+ class User < ActiveRecord::Base
53
+ act_as_liker
54
+
55
+ validates :username, { presence: true, uniqueness: true }
56
+ end
57
+ ```
58
+
59
+ ### Likee object methods
60
+ ```ruby
61
+ post.is_likee? # returns true
62
+
63
+ post.liked_by?(user) # returns true if user likes the post object, false otherwise
64
+
65
+ post.likers_by(User) # returns a scope of LikeSystem::Like join model that belongs to the post object and belongs to liker objects of type User
66
+ ```
67
+
68
+
69
+ ### Liker object methods
70
+ ```ruby
71
+ user.is_liker? # returns true
72
+
73
+ user.like(post) # Creates an instance of LikeSystem::Like join model associating the user object and the post object, returns true if succeded, false otherwise
74
+
75
+ user.unlike(post) # Destroys an instance of LikeSystem::Like join model that associates the user object and the post object, returns true if succeded, false otherwise
76
+
77
+ user.toggle_like(post) # Likes / unlikes the post
78
+
79
+ user.likes?(post) # returns true if the user object likes the post object, false otherwise
80
+
81
+ user.likees_by(Post) # returns a scope of LikeSystem::Like join model that belongs to the user object and belongs to likee objects of type Post
82
+ ```
83
+
84
+ For more information read the [api documentation](http://rubydoc.info/gems/like_system).
85
+
86
+ ## Contributing
87
+
88
+ 1. Fork it ( https://github.com/pmviva/like_system/fork )
89
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
90
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
91
+ 4. Push to the branch (`git push origin my-new-feature`)
92
+ 5. Create a new Pull Request
93
+
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ task :default => [:spec]
4
+ desc 'run Rspec specs'
5
+ task :spec do
6
+ sh 'rspec spec'
7
+ end
8
+
data/gemfiles/.empty ADDED
File without changes
File without changes
data/gemfiles/.keep ADDED
File without changes
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "4.1.10"
6
+
7
+ gemspec :path => "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "4.2.1"
6
+
7
+ gemspec :path => "../"
data/lib/.empty ADDED
File without changes
data/lib/.gitignore ADDED
File without changes
data/lib/.keep ADDED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,46 @@
1
+ require 'rails/generators/migration'
2
+ require 'rails/generators/active_record'
3
+
4
+ ###
5
+ # LikeSystemGenerator class
6
+ #
7
+ # This class generates the like model migration in like system
8
+ ###
9
+ class LikeSystemGenerator < Rails::Generators::Base
10
+ ###
11
+ # Includes Rails::Generators::Migration
12
+ ###
13
+ include Rails::Generators::Migration
14
+
15
+ ###
16
+ # Generator description definition
17
+ ###
18
+ desc "Generates a migration for the Like model"
19
+
20
+ ###
21
+ # Retrieves the source root
22
+ #
23
+ # @return [String]
24
+ ###
25
+ def self.source_root
26
+ @source_root ||= File.dirname(__FILE__) + '/templates'
27
+ end
28
+
29
+ ###
30
+ # Retrieves the next migration number
31
+ #
32
+ # @path [String] path - the path to calculate the next migration number
33
+ # @return [String]
34
+ ###
35
+ def self.next_migration_number(path)
36
+ ActiveRecord::Generators::Base.next_migration_number(path)
37
+ end
38
+
39
+ ###
40
+ # Generates the migration
41
+ ###
42
+ def generate_migration
43
+ migration_template 'migration.rb', 'db/migrate/create_likes.rb'
44
+ end
45
+ end
46
+
File without changes
File without changes
File without changes
@@ -0,0 +1,47 @@
1
+ ###
2
+ # CreateLikes class
3
+ #
4
+ # This class defines the create likes migration in like system
5
+ ###
6
+ class CreateLikes < ActiveRecord::Migration
7
+ ###
8
+ # Changes the database
9
+ ###
10
+ def change
11
+ ###
12
+ # Likes table creation
13
+ ###
14
+ create_table :likes do |t|
15
+ ###
16
+ # Likee id field and likee type field definition
17
+ ###
18
+ t.references :likee, polymorphic: true
19
+
20
+ ###
21
+ # Liker id fiel and liker type field definition
22
+ ###
23
+ t.references :liker, polymorphic: true
24
+
25
+ ###
26
+ # Timestamps fields definition
27
+ ###
28
+ t.timestamps null: false
29
+ end
30
+
31
+ ###
32
+ # Likes table likee id field and likee type field index addition
33
+ ###
34
+ add_index :likes, [:likee_id, :likee_type], name: "likes_likee_idx"
35
+
36
+ ###
37
+ # Likes table liker id field and liker type field index addition
38
+ ###
39
+ add_index :likes, [:liker_id, :liker_type], name: "likes_liker_idx"
40
+
41
+ ###
42
+ # Likes table likee id field and likee type field and liker id field and liker type field unique index addition
43
+ ###
44
+ add_index :likes, [:likee_id, :likee_type, :liker_id, :liker_type], name: "likes_likee_liker_idx", unique: true
45
+ end
46
+ end
47
+
@@ -0,0 +1,45 @@
1
+ require 'like_system/like'
2
+ require 'like_system/likee'
3
+ require 'like_system/liker'
4
+
5
+ ###
6
+ # LikeSystem module
7
+ #
8
+ # This module defines common behavior in like system
9
+ ###
10
+ module LikeSystem
11
+ ###
12
+ # Specifies if self can be liked by {Liker} objects
13
+ #
14
+ # @return [Boolean]
15
+ ###
16
+ def is_likee?
17
+ false
18
+ end
19
+
20
+ ###
21
+ # Specifies if self can like {Likee} objects
22
+ #
23
+ # @return [Boolean]
24
+ ###
25
+ def is_liker?
26
+ false
27
+ end
28
+
29
+ ###
30
+ # Instructs self to act as likee
31
+ ###
32
+ def act_as_likee
33
+ include Likee
34
+ end
35
+
36
+ ###
37
+ # Instructs self to act as liker
38
+ ###
39
+ def act_as_liker
40
+ include Liker
41
+ end
42
+ end
43
+
44
+ ActiveRecord::Base.extend LikeSystem
45
+
File without changes
File without changes
File without changes
@@ -0,0 +1,155 @@
1
+ ###
2
+ # LikeSystem module
3
+ #
4
+ # This module defines common behavior in like system
5
+ ###
6
+ module LikeSystem
7
+ ###
8
+ # Like class
9
+ #
10
+ # This class defines the like model in like system
11
+ ###
12
+ class Like < ActiveRecord::Base
13
+ ###
14
+ # Belongs to likee association configuration
15
+ ###
16
+ belongs_to :likee, polymorphic: :true
17
+
18
+ ###
19
+ # Belongs to liker association configuration
20
+ ###
21
+ belongs_to :liker, polymorphic: :true
22
+
23
+ ###
24
+ # Creates a {Like} relationship between a {Liker} object and a {Likee} object
25
+ #
26
+ # @param [Liker] liker - the {Liker} of the relationship
27
+ # @param [Likee] likee - the {Likee} of the relationship
28
+ # @return [Boolean]
29
+ ###
30
+ def self.like(liker, likee)
31
+ validate_likee(likee)
32
+ validate_liker(liker)
33
+
34
+ if likes?(liker, likee)
35
+ false
36
+ else
37
+ like = scope_by_liker(liker).scope_by_likee(likee).build
38
+ like.save
39
+ true
40
+ end
41
+ end
42
+
43
+ ###
44
+ # Destroys a {Like} relationship between a {Liker} object and a {Likee} object
45
+ #
46
+ # @param [Liker] liker - the {Liker} of the relationship
47
+ # @param [Likee] likee - the {Likee} of the relationship
48
+ # @return [Boolean]
49
+ ###
50
+ def self.unlike(liker, likee)
51
+ validate_likee(likee)
52
+ validate_liker(liker)
53
+
54
+ if likes?(liker, likee)
55
+ like = scope_by_liker(liker).scope_by_likee(likee).take
56
+ like.destroy
57
+ true
58
+ else
59
+ false
60
+ end
61
+ end
62
+
63
+ ###
64
+ # Toggles a {Like} relationship between a {Liker} object and a {Likee} object
65
+ #
66
+ # @param [Liker] liker - the {Liker} of the relationship
67
+ # @param [Likee] likee - the {Likee} of the relationship
68
+ # @return [Boolean]
69
+ ###
70
+ def self.toggle_like(liker, likee)
71
+ validate_likee(likee)
72
+ validate_liker(liker)
73
+
74
+ if likes?(liker, likee)
75
+ unlike(liker, likee)
76
+ else
77
+ like(liker, likee)
78
+ end
79
+ end
80
+
81
+ ###
82
+ # Specifies if a {Liker} object likes a {Likee} object
83
+ #
84
+ # @param [Liker] liker - the {Liker} object to test against
85
+ # @param [Likee] likee - the {Likee} object to test against
86
+ # @return [Boolean]
87
+ ###
88
+ def self.likes?(liker, likee)
89
+ validate_likee(likee)
90
+ validate_liker(liker)
91
+
92
+ scope_by_liker(liker).scope_by_likee(likee).exists?
93
+ end
94
+
95
+ ###
96
+ # Retrieves a scope of {Like} objects filtered by a {Likee} object
97
+ #
98
+ # @param [Likee] likee - the {Likee} to filter
99
+ # @return [ActiveRecord::Relation]
100
+ ###
101
+ def self.scope_by_likee(likee)
102
+ where(likee: likee)
103
+ end
104
+
105
+ ###
106
+ # Retrieves a scope of {Like} objects filtered by a {Likee} type
107
+ #
108
+ # @param [Class] klass - the {Class} to filter
109
+ # @return [ActiveRecord::Relation]
110
+ ###
111
+ def self.scope_by_likee_type(klass)
112
+ where(likee_type: klass.to_s.classify)
113
+ end
114
+
115
+ ###
116
+ # Retrieves a scope of {Like} objects filtered by a {Liker} object
117
+ #
118
+ # @param [Liker] liker - the {Liker} to filter
119
+ # @return [ActiveRecord::Relation]
120
+ ###
121
+ def self.scope_by_liker(liker)
122
+ where(liker: liker)
123
+ end
124
+
125
+ ###
126
+ # Retrieves a scope of {Like} objects filtered by a {Liker} type
127
+ #
128
+ # @param [Class] klass - the {Class} to filter
129
+ # @return [ActiveRecord::Relation]
130
+ ###
131
+ def self.scope_by_liker_type(klass)
132
+ where(liker_type: klass.to_s.classify)
133
+ end
134
+
135
+ private
136
+ ###
137
+ # Validates a likee object
138
+ #
139
+ # @raise [ArgumentError] if the likee object is invalid
140
+ ###
141
+ def self.validate_likee(likee)
142
+ raise ArgumentError.new unless likee.respond_to?(:is_likee?) && likee.is_likee?
143
+ end
144
+
145
+ ###
146
+ # Validates a liker object
147
+ #
148
+ # @raise [ArgumentError] if the liker object is invalid
149
+ ###
150
+ def self.validate_liker(liker)
151
+ raise ArgumentError.new unless liker.respond_to?(:is_liker?) && liker.is_liker?
152
+ end
153
+ end
154
+ end
155
+