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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 155b369ed874cd99a36550bd59743e5dff9244e3
4
- data.tar.gz: 9bf44af699eee62027b0e36f9dabea7f68e337b2
3
+ metadata.gz: a1d364ddeb1931ffe4576c08d28fd330297b3c67
4
+ data.tar.gz: 2032192d22e7955be1c55d118c40b8ac70ffda6b
5
5
  SHA512:
6
- metadata.gz: 35faff491ee821bf3c0255e236613a8904ca5e816371775316af688bbc27621d15d33e3fb951297e8b359ee44e16fbf6dad1ac620e26cd6aec9cce7aca0c8e5e
7
- data.tar.gz: a2a78b255a646c9cbb75317e5eabeb58694ab6464c25162911b51aed56f647c9b94702aad300ced1c700a492d8fa7764843a85daea4fa2dff426bcaf096c87a9
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.1.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 then, probably in an initializer, tell Like how to determine who the currently signed in user is, along with any filters you wish the underlying controller to implement:
31
+ And mount the necessary routes (which are already namespaced under `/like`):
32
32
 
33
33
  ```ruby
34
- Like.controllers[:user] = lambda { |controller|
35
- controller.current_user
36
- }
37
- Like.controllers[:filter] = lambda { |controller|
38
- controller.authenticate_user!
39
- }
34
+ Rails.application.routes.draw do
35
+ # ...
36
+ mount Like::Engine => '/'
37
+ # ...
38
+ end
40
39
  ```
41
40
 
42
- The above example is exactly what you'd need if you're using Devise with a User model.
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
- Of course, you probably want to know how many likes an object has:
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 +1,6 @@
1
1
  require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task :default => :spec
@@ -1,29 +1,19 @@
1
- class Like::LikesController < ActionController::Base
2
- before_filter :like_filters
1
+ class Like::LikesController < ApplicationController
2
+ before_filter { interaction.pre_action }
3
3
 
4
4
  def create
5
- Like::Like.like user, likeable
6
-
7
- redirect_to :back
5
+ interaction.create
6
+ interaction.post_action
8
7
  end
9
8
 
10
9
  def destroy
11
- Like::Like.unlike user, likeable
12
-
13
- redirect_to :back
10
+ interaction.destroy
11
+ interaction.post_action
14
12
  end
15
13
 
16
14
  private
17
15
 
18
- def like_filters
19
- Like.controllers[:filter].call self
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
@@ -1,4 +1,4 @@
1
- Rails.application.routes.draw do
1
+ Like::Engine.routes.draw do
2
2
  namespace :like do
3
3
  post 'likes', to: 'likes#create', as: :likes
4
4
  delete 'likes', to: 'likes#destroy'
data/lib/like.rb CHANGED
@@ -1,12 +1,11 @@
1
1
  require 'rails'
2
2
 
3
3
  module Like
4
- def self.controllers
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.1.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
- Like.controllers[:user] = lambda { |controller| user }
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.controllers[:user] = lambda { |controller| controller.current_user }
10
- Like.controllers[:filter] = lambda { |controller|
11
- controller.authenticate_user!
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
@@ -3,5 +3,8 @@ Rails.application.routes.draw do
3
3
 
4
4
  resources :articles
5
5
 
6
+ mount Like::Engine => '/'
7
+ mount Like::API => '/api/likes'
8
+
6
9
  root to: 'articles#index'
7
10
  end
data/spec/spec_helper.rb CHANGED
@@ -3,6 +3,7 @@ require 'bundler'
3
3
  Bundler.setup :default, :development
4
4
 
5
5
  require 'combustion'
6
+ require 'grape'
6
7
  require 'like'
7
8
  require 'devise'
8
9
 
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.1.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-17 00:00:00.000000000 Z
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