like 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +10 -0
- data/README.md +61 -10
- data/Rakefile +5 -0
- data/app/controllers/like/likes_controller.rb +8 -18
- data/app/helpers/like/likes_helper.rb +2 -2
- data/config/routes.rb +1 -1
- data/lib/like.rb +5 -6
- data/lib/like/api.rb +23 -0
- data/lib/like/interaction.rb +34 -0
- data/like.gemspec +3 -1
- data/spec/acceptance/liking_spec.rb +6 -1
- data/spec/acceptance/liking_with_api_spec.rb +46 -0
- data/spec/acceptance/liking_with_devise_spec.rb +11 -4
- data/spec/internal/config/routes.rb +3 -0
- data/spec/spec_helper.rb +1 -0
- metadata +35 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1d364ddeb1931ffe4576c08d28fd330297b3c67
|
4
|
+
data.tar.gz: 2032192d22e7955be1c55d118c40b8ac70ffda6b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dfd5b75bde0e112a63f8aec7b9e944e79823d78c2ed235a20ec45abc91e7c0dda7d8faa5271f256ef7997b8af85539ffe84608672315cebbc7d0f4cd327c401e
|
7
|
+
data.tar.gz: e3ef5b7a09397c11d5d15b4ae9d18a09f075d5579590a7c87f93e37056e120a38a0d328744eb72bf488c218859d7e2cf4efcb8e3e1bf2e58436ba7fbd1cf5bde
|
data/.travis.yml
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 1.9.3
|
4
|
+
- 2.0.0
|
5
|
+
notifications:
|
6
|
+
campfire:
|
7
|
+
rooms:
|
8
|
+
- secure: "QZhh0pcYx9OCxAxQMMl411Wa/F98oXGCv/z4VwoEHjXIWaFyt3nL1cha1NFd4Kw2b9+z81q90lLvSWjcZkL9/EUoOZpDNw6KhFQ4Y4B2UwYSHzFRSFDMc7RcpJf7fXbEuXA1k8nZ5yd77eoJro0U6UyPou0V2xWr9WETx5v4Llc="
|
9
|
+
on_success: change
|
10
|
+
on_failure: change
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@ A simple Rails engine for liking ActiveRecord objects.
|
|
6
6
|
|
7
7
|
Add this line to your application's Gemfile:
|
8
8
|
|
9
|
-
gem 'like', '0.
|
9
|
+
gem 'like', '0.2.0'
|
10
10
|
|
11
11
|
Don't forget to bundle:
|
12
12
|
|
@@ -28,20 +28,35 @@ All you need to do to use this engine is have something like the following in yo
|
|
28
28
|
<% end %>
|
29
29
|
```
|
30
30
|
|
31
|
-
And
|
31
|
+
And mount the necessary routes (which are already namespaced under `/like`):
|
32
32
|
|
33
33
|
```ruby
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
}
|
34
|
+
Rails.application.routes.draw do
|
35
|
+
# ...
|
36
|
+
mount Like::Engine => '/'
|
37
|
+
# ...
|
38
|
+
end
|
40
39
|
```
|
41
40
|
|
42
|
-
|
41
|
+
By default, Like presumes the object that the like is created by (the liker) is available through the `current_user` method in a standard controller inheriting from ApplicationController.
|
43
42
|
|
44
|
-
|
43
|
+
If you wish to customise this, you'll need to subclass from Like::Interaction and override the `liker` method. The same goes for adding in methods to be called as part of a before filter. Here's an implementation that's Devise-friendly:
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
Like.interaction_class = Class.new(Like::Interaction) do
|
47
|
+
def pre_action
|
48
|
+
controller.authenticate_user!
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def liker
|
54
|
+
controller.current_user
|
55
|
+
end
|
56
|
+
end
|
57
|
+
```
|
58
|
+
|
59
|
+
At some point, you'll probably want to know how many likes an object has:
|
45
60
|
|
46
61
|
```ruby
|
47
62
|
Like::Like.with_likeable(article).count
|
@@ -55,6 +70,42 @@ Like::Like.with_liker(user).count
|
|
55
70
|
|
56
71
|
Like doesn't care if your user model is called something else - it's a polymorphic association under the hood, so anything is accepted as the 'liker'. The same applies for 'likeable' as well.
|
57
72
|
|
73
|
+
## Usage as an API
|
74
|
+
|
75
|
+
Like comes with an optional API you can mount instead of the standard ActionController controller. You'll need to add Grape (0.5 or newer) to your Gemfile as well, and then the API can be mounted wherever you like. There's simple POST and DELETE endpoints at the root of the API, and they accept two parameters following ActiveRecord polymorphic defaults: likeable_type and likeable_id.
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
Rails.application.routes.draw do
|
79
|
+
# mounting the following:
|
80
|
+
mount Like::API => '/api/likes'
|
81
|
+
# adds to endpoints:
|
82
|
+
# POST /api/likes
|
83
|
+
# DELETE /api/likes
|
84
|
+
|
85
|
+
# ...
|
86
|
+
end
|
87
|
+
```
|
88
|
+
|
89
|
+
You'll want to tweak the interaction class so the post_action returns something useful (instead of the default redirect, which is meaningless in the API context), and ensure the liker is set as well. Here's an example (again, it's Devise-friendly):
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
Like.interaction_class = Class.new(Like::Interaction) do
|
93
|
+
def pre_action
|
94
|
+
error!('403 Forbidden', 403) unless liker
|
95
|
+
end
|
96
|
+
|
97
|
+
def post_action
|
98
|
+
{'status' => 'OK'}
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def liker
|
104
|
+
env['warden'].authenticated?(:user) ? env['warden'].user(:user) : nil
|
105
|
+
end
|
106
|
+
end
|
107
|
+
```
|
108
|
+
|
58
109
|
## Contributing
|
59
110
|
|
60
111
|
1. Fork it
|
data/Rakefile
CHANGED
@@ -1,29 +1,19 @@
|
|
1
|
-
class Like::LikesController <
|
2
|
-
before_filter
|
1
|
+
class Like::LikesController < ApplicationController
|
2
|
+
before_filter { interaction.pre_action }
|
3
3
|
|
4
4
|
def create
|
5
|
-
|
6
|
-
|
7
|
-
redirect_to :back
|
5
|
+
interaction.create
|
6
|
+
interaction.post_action
|
8
7
|
end
|
9
8
|
|
10
9
|
def destroy
|
11
|
-
|
12
|
-
|
13
|
-
redirect_to :back
|
10
|
+
interaction.destroy
|
11
|
+
interaction.post_action
|
14
12
|
end
|
15
13
|
|
16
14
|
private
|
17
15
|
|
18
|
-
def
|
19
|
-
Like.
|
20
|
-
end
|
21
|
-
|
22
|
-
def likeable
|
23
|
-
likeable = params[:likeable_type].constantize.find params[:likeable_id]
|
24
|
-
end
|
25
|
-
|
26
|
-
def user
|
27
|
-
Like.controllers[:user].call self
|
16
|
+
def interaction
|
17
|
+
@interaction ||= Like.interaction_class.new self
|
28
18
|
end
|
29
19
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module Like::LikesHelper
|
2
2
|
def like_path_for(likeable)
|
3
|
-
like_likes_path likeable_to_params(likeable)
|
3
|
+
like.like_likes_path likeable_to_params(likeable)
|
4
4
|
end
|
5
5
|
|
6
6
|
def like_url_for(likeable)
|
7
|
-
like_likes_url likeable_to_params(likeable)
|
7
|
+
like.like_likes_url likeable_to_params(likeable)
|
8
8
|
end
|
9
9
|
|
10
10
|
def likeable_to_params(likeable)
|
data/config/routes.rb
CHANGED
data/lib/like.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
require 'rails'
|
2
2
|
|
3
3
|
module Like
|
4
|
-
|
5
|
-
@controllers ||= {
|
6
|
-
user: lambda { |controller| controller.current_user },
|
7
|
-
filter: lambda { |controller| true }
|
8
|
-
}
|
9
|
-
end
|
4
|
+
mattr_accessor :interaction_class
|
10
5
|
end
|
11
6
|
|
12
7
|
require 'like/engine'
|
8
|
+
require 'like/interaction'
|
9
|
+
require 'like/api' if defined?(Grape)
|
10
|
+
|
11
|
+
Like.interaction_class = Like::Interaction
|
data/lib/like/api.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
class Like::API < Grape::API
|
2
|
+
format :json
|
3
|
+
|
4
|
+
helpers do
|
5
|
+
def interaction
|
6
|
+
@interaction = Like.interaction_class.new self
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
before do
|
11
|
+
interaction.pre_action
|
12
|
+
end
|
13
|
+
|
14
|
+
post do
|
15
|
+
interaction.create
|
16
|
+
interaction.post_action
|
17
|
+
end
|
18
|
+
|
19
|
+
delete do
|
20
|
+
interaction.destroy
|
21
|
+
interaction.post_action
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class Like::Interaction
|
2
|
+
def initialize(controller)
|
3
|
+
@controller = controller
|
4
|
+
end
|
5
|
+
|
6
|
+
def create
|
7
|
+
Like::Like.like liker, likeable
|
8
|
+
end
|
9
|
+
|
10
|
+
def destroy
|
11
|
+
Like::Like.unlike liker, likeable
|
12
|
+
end
|
13
|
+
|
14
|
+
def post_action
|
15
|
+
controller.redirect_to :back
|
16
|
+
end
|
17
|
+
|
18
|
+
def pre_action
|
19
|
+
#
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :controller
|
25
|
+
delegate :params, to: :controller
|
26
|
+
|
27
|
+
def likeable
|
28
|
+
@likeable ||= params[:likeable_type].constantize.find params[:likeable_id]
|
29
|
+
end
|
30
|
+
|
31
|
+
def liker
|
32
|
+
controller.current_user
|
33
|
+
end
|
34
|
+
end
|
data/like.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
Gem::Specification.new do |spec|
|
3
3
|
spec.name = 'like'
|
4
|
-
spec.version = '0.
|
4
|
+
spec.version = '0.2.0'
|
5
5
|
spec.authors = ['Pat Allan']
|
6
6
|
spec.email = ['pat@freelancing-gods.com']
|
7
7
|
spec.summary = %q{Rails Engine for liking}
|
@@ -19,6 +19,8 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.add_development_dependency 'capybara', '~> 2.2.0'
|
20
20
|
spec.add_development_dependency 'combustion', '~> 0.5.1'
|
21
21
|
spec.add_development_dependency 'devise', '~> 3.2.2'
|
22
|
+
spec.add_development_dependency 'grape', '~> 0.5'
|
23
|
+
spec.add_development_dependency 'mime-types', '~> 1.16'
|
22
24
|
spec.add_development_dependency 'rspec-rails', '~> 2.14.0'
|
23
25
|
spec.add_development_dependency 'sqlite3', '~> 1.3.8'
|
24
26
|
end
|
@@ -17,7 +17,12 @@ describe 'Liking an object' do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it "saves the like through a web request" do
|
20
|
-
|
20
|
+
user
|
21
|
+
Like.interaction_class = Class.new(Like::Interaction) do
|
22
|
+
def liker
|
23
|
+
User.first
|
24
|
+
end
|
25
|
+
end
|
21
26
|
|
22
27
|
post '/like/likes', {likeable_type: 'Article', likeable_id: article.id},
|
23
28
|
{'HTTP_REFERER' => '/'}
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Liking an object' do
|
4
|
+
let(:user) { User.create! email: 'pat@test.com', password: 'password',
|
5
|
+
password_confirmation: 'password' }
|
6
|
+
let(:article) { Article.create! }
|
7
|
+
|
8
|
+
before :each do
|
9
|
+
user
|
10
|
+
|
11
|
+
Like.interaction_class = Class.new(Like::Interaction) do
|
12
|
+
def post_action
|
13
|
+
{'status' => 'OK'}
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def liker
|
19
|
+
User.first
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it "saves the like" do
|
25
|
+
post '/api/likes', likeable_type: 'Article', likeable_id: article.id
|
26
|
+
|
27
|
+
likes = Like::Like.where(
|
28
|
+
liker_type: 'User', liker_id: user.id,
|
29
|
+
likeable_type: 'Article', likeable_id: article.id
|
30
|
+
)
|
31
|
+
|
32
|
+
expect(likes.count).to eq(1)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "can delete the like" do
|
36
|
+
post '/api/likes', likeable_type: 'Article', likeable_id: article.id
|
37
|
+
delete '/api/likes', likeable_type: 'Article', likeable_id: article.id
|
38
|
+
|
39
|
+
likes = Like::Like.where(
|
40
|
+
liker_type: 'User', liker_id: user.id,
|
41
|
+
likeable_type: 'Article', likeable_id: article.id
|
42
|
+
)
|
43
|
+
|
44
|
+
expect(likes.count).to eq(0)
|
45
|
+
end
|
46
|
+
end
|
@@ -6,10 +6,17 @@ describe 'Liking an object' do
|
|
6
6
|
let(:article) { Article.create! }
|
7
7
|
|
8
8
|
before :each do
|
9
|
-
Like.
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
Like.interaction_class = Class.new(Like::Interaction) do
|
10
|
+
def pre_action
|
11
|
+
controller.authenticate_user!
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def liker
|
17
|
+
controller.current_user
|
18
|
+
end
|
19
|
+
end
|
13
20
|
end
|
14
21
|
|
15
22
|
context 'authenticated' do
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: like
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pat Allan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-12-
|
11
|
+
date: 2013-12-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -66,6 +66,34 @@ dependencies:
|
|
66
66
|
- - ~>
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 3.2.2
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: grape
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.5'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.5'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: mime-types
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.16'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.16'
|
69
97
|
- !ruby/object:Gem::Dependency
|
70
98
|
name: rspec-rails
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -102,6 +130,7 @@ extensions: []
|
|
102
130
|
extra_rdoc_files: []
|
103
131
|
files:
|
104
132
|
- .gitignore
|
133
|
+
- .travis.yml
|
105
134
|
- Gemfile
|
106
135
|
- LICENSE.txt
|
107
136
|
- README.md
|
@@ -113,9 +142,12 @@ files:
|
|
113
142
|
- config/routes.rb
|
114
143
|
- db/migrate/1_create_likes.rb
|
115
144
|
- lib/like.rb
|
145
|
+
- lib/like/api.rb
|
116
146
|
- lib/like/engine.rb
|
147
|
+
- lib/like/interaction.rb
|
117
148
|
- like.gemspec
|
118
149
|
- spec/acceptance/liking_spec.rb
|
150
|
+
- spec/acceptance/liking_with_api_spec.rb
|
119
151
|
- spec/acceptance/liking_with_devise_spec.rb
|
120
152
|
- spec/internal/app/controllers/application_controller.rb
|
121
153
|
- spec/internal/app/controllers/articles_controller.rb
|
@@ -156,6 +188,7 @@ specification_version: 4
|
|
156
188
|
summary: Rails Engine for liking
|
157
189
|
test_files:
|
158
190
|
- spec/acceptance/liking_spec.rb
|
191
|
+
- spec/acceptance/liking_with_api_spec.rb
|
159
192
|
- spec/acceptance/liking_with_devise_spec.rb
|
160
193
|
- spec/internal/app/controllers/application_controller.rb
|
161
194
|
- spec/internal/app/controllers/articles_controller.rb
|