like 0.0.1 → 0.1.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: 747351a7296d5e1927d738f5a96b160c15e2c376
4
- data.tar.gz: 90097bcf0a08a378a37c86ef12ab79d1e51a8f3f
3
+ metadata.gz: 155b369ed874cd99a36550bd59743e5dff9244e3
4
+ data.tar.gz: 9bf44af699eee62027b0e36f9dabea7f68e337b2
5
5
  SHA512:
6
- metadata.gz: b20bc6c902121ff7e055677fd8b8abde771e6d542fc08fa767e72bdaf6892a7602a7f360772a4f56f864a8e80ca05f782e102e49be76345cd17659b3803d8497
7
- data.tar.gz: 54012e5f2bee7f2f00669734059eac5d10b3cdd2b18bda50631bdb3645ae385586e7f1fa49b8cfb9ba4d0641bbfa56d11acb26e8771954b216d3d7a7a0c60908
6
+ metadata.gz: 35faff491ee821bf3c0255e236613a8904ca5e816371775316af688bbc27621d15d33e3fb951297e8b359ee44e16fbf6dad1ac620e26cd6aec9cce7aca0c8e5e
7
+ data.tar.gz: a2a78b255a646c9cbb75317e5eabeb58694ab6464c25162911b51aed56f647c9b94702aad300ced1c700a492d8fa7764843a85daea4fa2dff426bcaf096c87a9
data/.gitignore CHANGED
@@ -11,6 +11,7 @@ doc/
11
11
  lib/bundler/man
12
12
  pkg
13
13
  rdoc
14
+ spec/internal/db/*.sqlite
14
15
  spec/reports
15
16
  test/tmp
16
17
  test/version_tmp
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.0.1'
9
+ gem 'like', '0.1.0'
10
10
 
11
11
  Don't forget to bundle:
12
12
 
@@ -16,7 +16,46 @@ Then, add the migrations to your app and update your database accordingly:
16
16
 
17
17
  $ rake like:install:migrations db:migrate
18
18
 
19
- ### Contributing
19
+ ## Usage
20
+
21
+ All you need to do to use this engine is have something like the following in your views:
22
+
23
+ ```erb
24
+ <% if Like::Like.liking?(current_user, article) %>
25
+ <%= link_to 'Unlike', like_path_for(article), method: :delete %>
26
+ <% else %>
27
+ <%= link_to 'Like', like_path_for(article), method: :post %>
28
+ <% end %>
29
+ ```
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:
32
+
33
+ ```ruby
34
+ Like.controllers[:user] = lambda { |controller|
35
+ controller.current_user
36
+ }
37
+ Like.controllers[:filter] = lambda { |controller|
38
+ controller.authenticate_user!
39
+ }
40
+ ```
41
+
42
+ The above example is exactly what you'd need if you're using Devise with a User model.
43
+
44
+ Of course, you probably want to know how many likes an object has:
45
+
46
+ ```ruby
47
+ Like::Like.with_likeable(article).count
48
+ ```
49
+
50
+ Or even how many likes a user has made:
51
+
52
+ ```ruby
53
+ Like::Like.with_liker(user).count
54
+ ```
55
+
56
+ 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
+
58
+ ## Contributing
20
59
 
21
60
  1. Fork it
22
61
  2. Create your feature branch (`git checkout -b my-new-feature`)
@@ -0,0 +1,29 @@
1
+ class Like::LikesController < ActionController::Base
2
+ before_filter :like_filters
3
+
4
+ def create
5
+ Like::Like.like user, likeable
6
+
7
+ redirect_to :back
8
+ end
9
+
10
+ def destroy
11
+ Like::Like.unlike user, likeable
12
+
13
+ redirect_to :back
14
+ end
15
+
16
+ private
17
+
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
28
+ end
29
+ end
@@ -0,0 +1,13 @@
1
+ module Like::LikesHelper
2
+ def like_path_for(likeable)
3
+ like_likes_path likeable_to_params(likeable)
4
+ end
5
+
6
+ def like_url_for(likeable)
7
+ like_likes_url likeable_to_params(likeable)
8
+ end
9
+
10
+ def likeable_to_params(likeable)
11
+ {likeable_type: likeable.class.name, likeable_id: likeable.id}
12
+ end
13
+ end
@@ -6,4 +6,25 @@ class Like::Like < ActiveRecord::Base
6
6
 
7
7
  validates :liker, presence: true
8
8
  validates :likeable, presence: true
9
+
10
+ scope :with_liker, lambda { |liker|
11
+ where liker_type: liker.class.name, liker_id: liker.id
12
+ }
13
+ scope :with_likeable, lambda { |likeable|
14
+ where likeable_type: likeable.class.name, likeable_id: likeable.id
15
+ }
16
+
17
+ def self.like(liker, likeable)
18
+ create liker: liker, likeable: likeable
19
+ end
20
+
21
+ def self.liking?(liker, likeable)
22
+ return false if liker.nil? || likeable.nil?
23
+
24
+ with_liker(liker).with_likeable(likeable).count > 0
25
+ end
26
+
27
+ def self.unlike(liker, likeable)
28
+ with_liker(liker).with_likeable(likeable).each &:destroy
29
+ end
9
30
  end
data/config.ru CHANGED
@@ -3,5 +3,5 @@ require 'bundler'
3
3
 
4
4
  Bundler.require :default, :development
5
5
 
6
- Combustion.initialize!
6
+ Combustion.initialize! :all
7
7
  run Combustion::Application
@@ -0,0 +1,6 @@
1
+ Rails.application.routes.draw do
2
+ namespace :like do
3
+ post 'likes', to: 'likes#create', as: :likes
4
+ delete 'likes', to: 'likes#destroy'
5
+ end
6
+ end
@@ -1,6 +1,11 @@
1
+ require 'rails'
2
+
1
3
  module Like
2
- def self.link(liker, likeable)
3
- Like::Like.create liker: liker, likeable: likeable
4
+ def self.controllers
5
+ @controllers ||= {
6
+ user: lambda { |controller| controller.current_user },
7
+ filter: lambda { |controller| true }
8
+ }
4
9
  end
5
10
  end
6
11
 
@@ -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.0.1'
4
+ spec.version = '0.1.0'
5
5
  spec.authors = ['Pat Allan']
6
6
  spec.email = ['pat@freelancing-gods.com']
7
7
  spec.summary = %q{Rails Engine for liking}
@@ -16,7 +16,9 @@ Gem::Specification.new do |spec|
16
16
 
17
17
  spec.add_runtime_dependency 'rails', '>= 3.2'
18
18
 
19
+ spec.add_development_dependency 'capybara', '~> 2.2.0'
19
20
  spec.add_development_dependency 'combustion', '~> 0.5.1'
21
+ spec.add_development_dependency 'devise', '~> 3.2.2'
20
22
  spec.add_development_dependency 'rspec-rails', '~> 2.14.0'
21
23
  spec.add_development_dependency 'sqlite3', '~> 1.3.8'
22
24
  end
@@ -1,11 +1,26 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'Liking an object' do
4
- let(:user) { User.create! }
4
+ let(:user) { User.create! email: 'pat@test.com', password: 'password',
5
+ password_confirmation: 'password' }
5
6
  let(:article) { Article.create! }
6
7
 
7
8
  it "saves the like" do
8
- Like.link user, article
9
+ Like::Like.like user, article
10
+
11
+ likes = Like::Like.where(
12
+ liker_type: 'User', liker_id: user.id,
13
+ likeable_type: 'Article', likeable_id: article.id
14
+ )
15
+
16
+ expect(likes.count).to eq(1)
17
+ end
18
+
19
+ it "saves the like through a web request" do
20
+ Like.controllers[:user] = lambda { |controller| user }
21
+
22
+ post '/like/likes', {likeable_type: 'Article', likeable_id: article.id},
23
+ {'HTTP_REFERER' => '/'}
9
24
 
10
25
  likes = Like::Like.where(
11
26
  liker_type: 'User', liker_id: user.id,
@@ -0,0 +1,71 @@
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
+ Like.controllers[:user] = lambda { |controller| controller.current_user }
10
+ Like.controllers[:filter] = lambda { |controller|
11
+ controller.authenticate_user!
12
+ }
13
+ end
14
+
15
+ context 'authenticated' do
16
+ before :each do
17
+ visit new_user_session_path
18
+
19
+ fill_in 'Email', with: user.email
20
+ fill_in 'Password', with: user.password
21
+
22
+ click_button 'Sign in'
23
+ end
24
+
25
+ it "saves the like" do
26
+ visit article_path(article)
27
+ click_link 'Like'
28
+
29
+ likes = Like::Like.where(
30
+ liker_type: 'User', liker_id: user.id,
31
+ likeable_type: 'Article', likeable_id: article.id
32
+ )
33
+
34
+ expect(likes.count).to eq(1)
35
+ end
36
+
37
+ it "can delete the like" do
38
+ visit article_path(article)
39
+ click_link 'Like'
40
+ click_link 'Unlike'
41
+
42
+ likes = Like::Like.where(
43
+ liker_type: 'User', liker_id: user.id,
44
+ likeable_type: 'Article', likeable_id: article.id
45
+ )
46
+
47
+ expect(likes.count).to eq(0)
48
+ end
49
+ end
50
+
51
+ context 'unauthenticated' do
52
+ it "redirects to the sign in page" do
53
+ visit article_path(article)
54
+ click_link 'Like'
55
+
56
+ expect(page).to have_content('Sign in')
57
+ end
58
+
59
+ it "doesn't save a like" do
60
+ visit article_path(article)
61
+ click_link 'Like'
62
+
63
+ likes = Like::Like.where(
64
+ liker_type: 'User', liker_id: user.id,
65
+ likeable_type: 'Article', likeable_id: article.id
66
+ )
67
+
68
+ expect(likes.count).to eq(0)
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,3 @@
1
+ class ApplicationController < ActionController::Base
2
+ protect_from_forgery with: :exception
3
+ end
@@ -0,0 +1,9 @@
1
+ class ArticlesController < ApplicationController
2
+ def index
3
+ @articles = Article.all
4
+ end
5
+
6
+ def show
7
+ @article = Article.find params[:id]
8
+ end
9
+ end
@@ -1,3 +1,4 @@
1
1
  class User < ActiveRecord::Base
2
- #
2
+ devise :database_authenticatable, :registerable,
3
+ :recoverable, :rememberable, :trackable, :validatable
3
4
  end
@@ -0,0 +1,5 @@
1
+ <h1>Articles</h1>
2
+
3
+ <% @articles.each do |article| %>
4
+ <%= link_to "View #{article.id}", article %>
5
+ <% end %>
@@ -0,0 +1,5 @@
1
+ <% if Like::Like.liking?(current_user, @article) %>
2
+ <%= link_to 'Unlike', like_path_for(@article), method: :delete %>
3
+ <% else %>
4
+ <%= link_to 'Like', like_path_for(@article), method: :post %>
5
+ <% end %>
@@ -0,0 +1,16 @@
1
+ Devise.setup do |config|
2
+ config.secret_key = 'aa5e96a76400191fc1f76c44a6c3e0f4f37d9097be933fa5280c25fd3111ab9382d5a72c5a6879ebf0bfce62e18d5eabd5121fd2ef3bb8df49521f6e257223ac'
3
+
4
+ config.mailer_sender = 'pat@test.com'
5
+
6
+ require 'devise/orm/active_record'
7
+
8
+ config.case_insensitive_keys = [ :email ]
9
+ config.strip_whitespace_keys = [ :email ]
10
+ config.skip_session_storage = [:http_auth]
11
+ config.stretches = 1
12
+ config.allow_unconfirmed_access_for = 1.day
13
+ config.password_length = 8..128
14
+ config.reset_password_within = 6.hours
15
+ config.sign_out_via = :delete
16
+ end
@@ -1,3 +1,7 @@
1
1
  Rails.application.routes.draw do
2
- #
2
+ devise_for :users
3
+
4
+ resources :articles
5
+
6
+ root to: 'articles#index'
3
7
  end
@@ -4,6 +4,16 @@ ActiveRecord::Schema.define do
4
4
  end
5
5
 
6
6
  create_table :users, :force => true do |t|
7
+ t.string :email, default: "", null: false
8
+ t.string :encrypted_password, default: "", null: false
9
+ t.string :reset_password_token
10
+ t.datetime :reset_password_sent_at
11
+ t.datetime :remember_created_at
12
+ t.integer :sign_in_count, default: 0, null: false
13
+ t.datetime :current_sign_in_at
14
+ t.datetime :last_sign_in_at
15
+ t.string :current_sign_in_ip
16
+ t.string :last_sign_in_ip
7
17
  t.timestamps
8
18
  end
9
19
  end
@@ -4,13 +4,20 @@ Bundler.setup :default, :development
4
4
 
5
5
  require 'combustion'
6
6
  require 'like'
7
+ require 'devise'
7
8
 
8
9
  Combustion.initialize! :action_controller, :active_record
9
10
 
10
11
  require 'rspec/rails'
12
+ require 'capybara/rails'
11
13
 
12
14
  Dir["./spec/support/**/*.rb"].each { |file| require file }
13
15
 
14
16
  RSpec.configure do |config|
15
17
  config.use_transactional_fixtures = true
18
+
19
+ config.include RSpec::Rails::RequestExampleGroup, type: :request,
20
+ example_group: {file_path: /spec\/acceptance/}
21
+ config.include Capybara::DSL, type: :request,
22
+ example_group: {file_path: /spec\/acceptance/}
16
23
  end
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.0.1
4
+ version: 0.1.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-16 00:00:00.000000000 Z
11
+ date: 2013-12-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: capybara
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 2.2.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 2.2.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: combustion
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +52,20 @@ dependencies:
38
52
  - - ~>
39
53
  - !ruby/object:Gem::Version
40
54
  version: 0.5.1
55
+ - !ruby/object:Gem::Dependency
56
+ name: devise
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 3.2.2
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 3.2.2
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: rspec-rails
43
71
  requirement: !ruby/object:Gem::Requirement
@@ -78,18 +106,26 @@ files:
78
106
  - LICENSE.txt
79
107
  - README.md
80
108
  - Rakefile
109
+ - app/controllers/like/likes_controller.rb
110
+ - app/helpers/like/likes_helper.rb
81
111
  - app/models/like/like.rb
82
112
  - config.ru
113
+ - config/routes.rb
83
114
  - db/migrate/1_create_likes.rb
84
115
  - lib/like.rb
85
116
  - lib/like/engine.rb
86
117
  - like.gemspec
87
118
  - spec/acceptance/liking_spec.rb
119
+ - spec/acceptance/liking_with_devise_spec.rb
120
+ - spec/internal/app/controllers/application_controller.rb
121
+ - spec/internal/app/controllers/articles_controller.rb
88
122
  - spec/internal/app/models/article.rb
89
123
  - spec/internal/app/models/user.rb
124
+ - spec/internal/app/views/articles/index.html.erb
125
+ - spec/internal/app/views/articles/show.html.erb
90
126
  - spec/internal/config/database.yml
127
+ - spec/internal/config/initializers/devise.rb
91
128
  - spec/internal/config/routes.rb
92
- - spec/internal/db/combustion_test.sqlite
93
129
  - spec/internal/db/schema.rb
94
130
  - spec/internal/log/.gitignore
95
131
  - spec/internal/public/favicon.ico
@@ -120,11 +156,16 @@ specification_version: 4
120
156
  summary: Rails Engine for liking
121
157
  test_files:
122
158
  - spec/acceptance/liking_spec.rb
159
+ - spec/acceptance/liking_with_devise_spec.rb
160
+ - spec/internal/app/controllers/application_controller.rb
161
+ - spec/internal/app/controllers/articles_controller.rb
123
162
  - spec/internal/app/models/article.rb
124
163
  - spec/internal/app/models/user.rb
164
+ - spec/internal/app/views/articles/index.html.erb
165
+ - spec/internal/app/views/articles/show.html.erb
125
166
  - spec/internal/config/database.yml
167
+ - spec/internal/config/initializers/devise.rb
126
168
  - spec/internal/config/routes.rb
127
- - spec/internal/db/combustion_test.sqlite
128
169
  - spec/internal/db/schema.rb
129
170
  - spec/internal/log/.gitignore
130
171
  - spec/internal/public/favicon.ico