emotions 0.2.1 → 0.2.2

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.
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 2.0.0
5
+ - 1.9.3
6
+
7
+ script: "echo 'DO IT' && bundle exec rake spec"
data/README.md CHANGED
@@ -1,6 +1,16 @@
1
- # Emotions
2
-
3
- Emotions is a Ruby library that allows ActiveRecord records to express (and hopefully store) emotions about other records.
1
+ <p align="center">
2
+ <a href="https://github.com/mirego/emotions">
3
+ <img src="http://i.imgur.com/9fhaEY4.png" alt="Emotions" />
4
+ </a>
5
+ <br />
6
+ Emotions is a Ruby library that allows ActiveRecord records to<br /> express (and hopefully store) emotions about other records.
7
+ <br /><br />
8
+ <a href="https://rubygems.org/gems/emotions"><img src="https://badge.fury.io/rb/emotions.png" /></a>
9
+ <a href="https://codeclimate.com/github/mirego/emotions"><img src="https://codeclimate.com/github/mirego/emotions.png" /></a>
10
+ <a href="https://travis-ci.org/mirego/emotions"><img src="https://travis-ci.org/mirego/emotions.png?branch=master" /></a>
11
+ </p>
12
+
13
+ ---
4
14
 
5
15
  ## Installation
6
16
 
@@ -84,17 +94,24 @@ picture.happy_emotions_count
84
94
  # Quick lookup into the column and returns `1`
85
95
  ```
86
96
 
97
+ Same thing for emotional records. If there’s a `happy_emotions_count` column in the `User` model, Emotions will update it each time a record expresses a happy emotion towards another record.
98
+
99
+ ```ruby
100
+ user.happy_about!(picture)
101
+
102
+ user.happy_about.count
103
+ # SQL query that counts records and returns `1`
104
+
105
+ user.happy_emotions_count
106
+ # Quick lookup into the column and returns `1`
107
+ ```
108
+
87
109
  ## License
88
110
 
89
111
  `Emotions` is © 2013 [Mirego](http://www.mirego.com) and may be freely distributed under the [New BSD license](http://opensource.org/licenses/BSD-3-Clause). See the [`LICENSE.md`](https://github.com/mirego/emotions/blob/master/LICENSE.md) file.
90
112
 
91
113
  ## About Mirego
92
114
 
93
- Mirego is a team of passionate people who believe that work is a place where you can innovate and have fun.
94
- We proudly built mobile applications for
95
- [iPhone](http://mirego.com/en/iphone-app-development/ "iPhone application development"),
96
- [iPad](http://mirego.com/en/ipad-app-development/ "iPad application development"),
97
- [Android](http://mirego.com/en/android-app-development/ "Android application development"),
98
- [Blackberry](http://mirego.com/en/blackberry-app-development/ "Blackberry application development"),
99
- [Windows Phone](http://mirego.com/en/windows-phone-app-development/ "Windows Phone application development") and
100
- [Windows 8](http://mirego.com/en/windows-8-app-development/ "Windows 8 application development").
115
+ Mirego is a team of passionate people who believe that work is a place where you can innovate and have fun. We proudly build mobile applications for [iPhone](http://mirego.com/en/iphone-app-development/ "iPhone application development"), [iPad](http://mirego.com/en/ipad-app-development/ "iPad application development"), [Android](http://mirego.com/en/android-app-development/ "Android application development"), [Blackberry](http://mirego.com/en/blackberry-app-development/ "Blackberry application development"), [Windows Phone](http://mirego.com/en/windows-phone-app-development/ "Windows Phone application development") and [Windows 8](http://mirego.com/en/windows-8-app-development/ "Windows 8 application development") in beautiful Quebec City.
116
+
117
+ We also love [open-source software](http://open.mirego.com/) and we try to extract as much code as possible from our projects to give back to the community.
@@ -1,5 +1,6 @@
1
1
  require 'emotions/version'
2
2
 
3
+ require 'ostruct'
3
4
  require 'active_record'
4
5
  require 'emotions/errors'
5
6
  require 'emotions/emotion'
@@ -6,23 +6,10 @@ module Emotions
6
6
  validates :emotional, presence: true
7
7
  validates :emotive, presence: true
8
8
 
9
- validates_each :emotion do |record, attr, value|
10
- unless Emotions.emotions.include?(value.try(:to_sym))
11
- record.errors.add attr, I18n.t(:invalid, scope: [:errors, :messages])
12
- end
13
- end
14
-
15
- validates_each :emotional do |record, attr, value|
16
- if value.blank? || !value.class.try(:emotional?)
17
- record.errors.add attr, I18n.t(:invalid, scope: [:errors, :messages])
18
- end
19
- end
20
-
21
- validates_each :emotive do |record, attr, value|
22
- if value.blank? || !value.class.try(:emotive?)
23
- record.errors.add attr, I18n.t(:invalid, scope: [:errors, :messages])
24
- end
25
- end
9
+ # Custom validations
10
+ validate :ensure_valid_emotion_name
11
+ validate { ensure_valid_associated_record :emotional }
12
+ validate { ensure_valid_associated_record :emotive }
26
13
 
27
14
  # Associations
28
15
  belongs_to :emotional, polymorphic: true
@@ -34,8 +21,28 @@ module Emotions
34
21
 
35
22
  protected
36
23
 
24
+ # Update the `<emotion>_emotions_counter` for the emotive record
37
25
  def update_emotion_counter
38
26
  self.emotive.update_emotion_counter(self.emotion)
27
+ self.emotional.update_emotion_counter(self.emotion)
28
+ end
29
+
30
+ # Make sure we're using an allowed emotion name
31
+ def ensure_valid_emotion_name
32
+ unless Emotions.emotions.include?(self.emotion.try(:to_sym))
33
+ errors.add :emotion, I18n.t(:invalid, scope: [:errors, :messages])
34
+ end
35
+ end
36
+
37
+ # Make sure that both emotive and emotional records are actually able to
38
+ # express and/or receive emotions
39
+ def ensure_valid_associated_record(association)
40
+ value = send(association)
41
+ predicate = :"#{association}?"
42
+
43
+ if !value.class.respond_to?(predicate) || !value.class.send(predicate)
44
+ errors.add association, I18n.t(:invalid, scope: [:errors, :messages])
45
+ end
39
46
  end
40
47
  end
41
48
  end
@@ -54,6 +54,15 @@ module Emotions
54
54
  _emotions_about(emotive).where(emotion: emotion).first.tap { |e| e.try(:destroy) }
55
55
  end
56
56
 
57
+ # @private
58
+ def update_emotion_counter(emotion)
59
+ attribute = "#{emotion}_emotions_count"
60
+
61
+ if self.respond_to?(attribute)
62
+ self.update_attribute(attribute, send("#{emotion}_about").count)
63
+ end
64
+ end
65
+
57
66
  module ClassMethods
58
67
  # Return an `ActiveRecord::Relation` containing the emotional records
59
68
  # that expressed a specific emotion towards an emotive record
@@ -88,8 +97,9 @@ module Emotions
88
97
  no_longer_express! #{emotion.inspect}, emotive
89
98
  end
90
99
 
91
- def #{emotion}_about(emotive)
92
- _emotions_about(emotive).where(emotion: #{emotion.to_s.inspect})
100
+ def #{emotion}_about(emotive = nil)
101
+ relation = emotive.nil? ? self.emotions : _emotions_about(emotive)
102
+ relation.where(emotion: #{emotion.to_s.inspect})
93
103
  end
94
104
 
95
105
  alias #{emotion}? #{emotion}_about?
@@ -1,3 +1,3 @@
1
1
  module Emotions
2
- VERSION = '0.2.1'
2
+ VERSION = '0.2.2'
3
3
  end
@@ -61,10 +61,12 @@ describe Emotions::Emotion do
61
61
  describe :Callbacks do
62
62
  describe :update_emotion_counter_on_create do
63
63
  let(:picture) { Picture.create }
64
- let(:emotion) { described_class.new(emotion: 'happy', emotional: User.create, emotive: picture) }
64
+ let(:user) { User.create }
65
+ let(:emotion) { described_class.new(emotion: 'happy', emotional: user, emotive: picture) }
65
66
 
66
67
  before do
67
68
  picture.should_receive(:update_emotion_counter).with('happy').once
69
+ user.should_receive(:update_emotion_counter).with('happy').once
68
70
  emotion.should_receive(:update_emotion_counter).once.and_call_original
69
71
  end
70
72
 
@@ -73,11 +75,13 @@ describe Emotions::Emotion do
73
75
 
74
76
  describe :update_emotion_counter_on_destroy do
75
77
  let(:picture) { Picture.create }
76
- let(:emotion) { described_class.new(emotion: 'happy', emotional: User.create, emotive: picture) }
78
+ let(:user) { User.create }
79
+ let(:emotion) { described_class.new(emotion: 'happy', emotional: user, emotive: picture) }
77
80
 
78
81
  before do
79
82
  emotion.save!
80
83
  picture.should_receive(:update_emotion_counter).with('happy').once
84
+ user.should_receive(:update_emotion_counter).with('happy').once
81
85
  emotion.should_receive(:update_emotion_counter).once.and_call_original
82
86
  end
83
87
 
@@ -5,7 +5,10 @@ describe Emotions::Emotional do
5
5
  emotions :happy, :sad
6
6
 
7
7
  run_migration do
8
- create_table(:users, force: true)
8
+ create_table(:users, force: true) do |t|
9
+ t.integer :happy_emotions_count, default: 0
10
+ t.integer :sad_emotions_count, default: 0
11
+ end
9
12
  create_table(:pictures, force: true)
10
13
  end
11
14
 
@@ -140,6 +143,20 @@ describe Emotions::Emotional do
140
143
  it { expect{ user.no_longer_happy_about! user }.to_not raise_error }
141
144
  end
142
145
  end
146
+
147
+ describe :update_emotion_counter do
148
+ let(:user) { User.create }
149
+ let(:relation) do
150
+ double.tap { |double| double.stub(:count).and_return(42) }
151
+ end
152
+
153
+ before do
154
+ User.any_instance.stub(:happy_about).and_return(relation)
155
+ user.update_emotion_counter(:happy)
156
+ end
157
+
158
+ it { expect(user.reload.happy_emotions_count).to eql 42 }
159
+ end
143
160
  end
144
161
  end
145
162
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: emotions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-19 00:00:00.000000000 Z
12
+ date: 2013-08-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -101,6 +101,7 @@ extra_rdoc_files: []
101
101
  files:
102
102
  - .gitignore
103
103
  - .rspec
104
+ - .travis.yml
104
105
  - Gemfile
105
106
  - LICENSE.md
106
107
  - README.md
@@ -137,7 +138,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
137
138
  version: '0'
138
139
  segments:
139
140
  - 0
140
- hash: -739399527715835013
141
+ hash: 4067111532583262534
141
142
  required_rubygems_version: !ruby/object:Gem::Requirement
142
143
  none: false
143
144
  requirements:
@@ -146,7 +147,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
146
147
  version: '0'
147
148
  segments:
148
149
  - 0
149
- hash: -739399527715835013
150
+ hash: 4067111532583262534
150
151
  requirements: []
151
152
  rubyforge_project:
152
153
  rubygems_version: 1.8.23