gutentag 0.2.2 → 0.3.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: aea053bcbf95bfcdacd4bbdf352a4b10d16ef561
4
- data.tar.gz: 6cc4798a3261163ba1369ac6d7736193fd2f1798
3
+ metadata.gz: dda4e9077e5d19af15ad0ae9bab60a64147f4c11
4
+ data.tar.gz: dcd0271e7e842c8edf3fc25ba1f4254c4853369a
5
5
  SHA512:
6
- metadata.gz: cfd4ef366f9dcfb50e650021689cca189e042893b76d80458350121071b31af511cafef0921ad6563e7bed781b59f40d6682682b0161ccc9154e20276e3ad804
7
- data.tar.gz: 7b2731e6f5cbb60ce6ec04fba73096942c53e9a9d2a1b4a38580c3c02b9861e6d23513f32cd0f632f914081639b8d7851e910ba1fcf2218800bb53bbf07c5e81
6
+ metadata.gz: fc49c2eaa8236fd2991c5213fb53bce4077890135185f0cf5730331603a384813fe0ecf3427d370719e11931044095ba65297c38052a43a4343e396311e77d68
7
+ data.tar.gz: b734e64f5731e2458af240c09a26e650a2d103d5d9bdb8649c52a0cf9d868cb1d06f1fd0fd61271c93b4764c3a7ea0dfa79b3f61ae5e6e932e042bd6321977ff
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # Gutentag
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/gutentag.png)](http://badge.fury.io/rb/gutentag)
3
4
  [![Build Status](https://travis-ci.org/pat/gutentag.png?branch=master)](https://travis-ci.org/pat/gutentag)
4
5
  [![Code Climate](https://codeclimate.com/github/pat/gutentag.png)](https://codeclimate.com/github/pat/gutentag)
5
6
 
@@ -11,7 +12,7 @@ This was built partly as a proof-of-concept, and partly to see how a tagging gem
11
12
 
12
13
  Get it into your Gemfile - and don't forget the version constraint!
13
14
 
14
- gem 'gutentag', '~> 0.2.2'
15
+ gem 'gutentag', '~> 0.3.0'
15
16
 
16
17
  Next: your tags get persisted to your database, so let's import and run the migrations to get the tables set up:
17
18
 
@@ -36,6 +37,11 @@ That's all it takes to get a tags association on each article. Of course, popula
36
37
  article.tag_names -= ['ruby']
37
38
  article.tag_names #=> ['pancakes', 'melbourne', 'portland']
38
39
 
40
+ Changes to tag_names are not persisted immediately - you must save your taggable object to have the tag changes reflected in your database:
41
+
42
+ article.tag_names << 'ruby'
43
+ article.save
44
+
39
45
  ## Licence
40
46
 
41
47
  Copyright (c) 2013, Gutentag is developed and maintained by Pat Allan, and is released under the open MIT Licence.
@@ -1,7 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  Gem::Specification.new do |s|
3
3
  s.name = 'gutentag'
4
- s.version = '0.2.2'
4
+ s.version = '0.3.0'
5
5
  s.authors = ['Pat Allan']
6
6
  s.email = ['pat@freelancing-gods.com']
7
7
  s.homepage = 'https://github.com/pat/gutentag'
@@ -4,5 +4,5 @@ end
4
4
 
5
5
  require 'gutentag/active_record'
6
6
  require 'gutentag/engine'
7
+ require 'gutentag/persistence'
7
8
  require 'gutentag/tag_name'
8
- require 'gutentag/tag_names'
@@ -9,18 +9,18 @@ module Gutentag::ActiveRecord
9
9
  :dependent => :destroy
10
10
  has_many :tags, :class_name => 'Gutentag::Tag',
11
11
  :through => :taggings
12
+
13
+ after_save Gutentag::Persistence
14
+
15
+ attr_writer :tag_names
12
16
  end
13
17
  end
14
18
 
15
- def tag_names
16
- @tag_names ||= Gutentag::TagNames.new self
19
+ def reset_tag_names
20
+ @tag_names = nil
17
21
  end
18
22
 
19
- def tag_names=(names)
20
- if names.is_a?(Gutentag::TagNames)
21
- @tag_names = names
22
- else
23
- @tag_names = Gutentag::TagNames.new_with_names self, names
24
- end
23
+ def tag_names
24
+ @tag_names ||= tags.collect(&:name)
25
25
  end
26
26
  end
@@ -0,0 +1,38 @@
1
+ class Gutentag::Persistence
2
+ def self.after_save(taggable)
3
+ new(taggable).persist
4
+ end
5
+
6
+ def initialize(taggable)
7
+ @taggable = taggable
8
+ @existing = normalised taggable.tags.collect(&:name)
9
+ @changes = normalised taggable.tag_names
10
+ end
11
+
12
+ def persist
13
+ remove_old
14
+ add_new
15
+
16
+ taggable.reset_tag_names
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :taggable, :existing, :changes
22
+
23
+ def add_new
24
+ (changes - existing).each do |name|
25
+ taggable.tags << Gutentag::Tag.find_or_create(name)
26
+ end
27
+ end
28
+
29
+ def normalised(names)
30
+ names.collect { |name| Gutentag::TagName.normalise(name) }.uniq
31
+ end
32
+
33
+ def remove_old
34
+ (existing - changes).each do |name|
35
+ taggable.tags.delete Gutentag::Tag.find_by_name(name)
36
+ end
37
+ end
38
+ end
@@ -8,11 +8,12 @@ describe "Managing tags via names" do
8
8
 
9
9
  article.tags << melbourne
10
10
 
11
- article.tag_names.to_a.should == ['melbourne']
11
+ article.tag_names.should == ['melbourne']
12
12
  end
13
13
 
14
14
  it "adds tags via their names" do
15
15
  article.tag_names << 'melbourne'
16
+ article.save!
16
17
 
17
18
  article.tags.collect(&:name).should == ['melbourne']
18
19
  end
@@ -20,32 +21,24 @@ describe "Managing tags via names" do
20
21
  it "doesn't complain when adding an existing tag" do
21
22
  article.tag_names << 'melbourne'
22
23
  article.tag_names << 'melbourne'
24
+ article.save!
23
25
 
24
26
  article.tags.collect(&:name).should == ['melbourne']
25
27
  end
26
28
 
27
29
  it "accepts a completely new set of tags" do
28
30
  article.tag_names = ['portland', 'oregon']
31
+ article.save!
29
32
 
30
33
  article.tags.collect(&:name).should == ['portland', 'oregon']
31
34
  end
32
35
 
33
- it "enumerates through tag names" do
34
- article.tag_names = ['melbourne', 'victoria']
35
- names = []
36
-
37
- article.tag_names.each do |name|
38
- names << name
39
- end
40
-
41
- names.should == ['melbourne', 'victoria']
42
- end
43
-
44
36
  it "does not allow duplication of tags" do
45
37
  existing = Article.create
46
38
  existing.tags << Gutentag::Tag.create(:name => 'portland')
47
39
 
48
40
  article.tag_names = ['portland']
41
+ article.save!
49
42
 
50
43
  existing.tag_ids.should == article.tag_ids
51
44
  end
@@ -53,6 +46,7 @@ describe "Managing tags via names" do
53
46
  it "appends tag names" do
54
47
  article.tag_names = ['portland']
55
48
  article.tag_names += ['oregon', 'ruby']
49
+ article.save!
56
50
 
57
51
  article.tags.collect(&:name).should == ['portland', 'oregon', 'ruby']
58
52
  end
@@ -60,6 +54,7 @@ describe "Managing tags via names" do
60
54
  it "does not repeat appended names that already exist" do
61
55
  article.tag_names = ['portland', 'oregon']
62
56
  article.tag_names += ['oregon', 'ruby']
57
+ article.save!
63
58
 
64
59
  article.tags.collect(&:name).should == ['portland', 'oregon', 'ruby']
65
60
  end
@@ -67,6 +62,7 @@ describe "Managing tags via names" do
67
62
  it "removes a single tag name" do
68
63
  article.tag_names = ['portland', 'oregon']
69
64
  article.tag_names.delete 'oregon'
65
+ article.save!
70
66
 
71
67
  article.tags.collect(&:name).should == ['portland']
72
68
  end
@@ -74,32 +70,28 @@ describe "Managing tags via names" do
74
70
  it "removes tag names" do
75
71
  article.tag_names = ['portland', 'oregon', 'ruby']
76
72
  article.tag_names -= ['oregon', 'ruby']
73
+ article.save!
77
74
 
78
75
  article.tags.collect(&:name).should == ['portland']
79
76
  end
80
77
 
81
- it "provides union operators" do
82
- article.tag_names = ['portland', 'ruby']
83
- article.tag_names |= ['ruby', 'melbourne']
84
-
85
- article.tags.collect(&:name).should == ['portland', 'ruby', 'melbourne']
86
- end
87
-
88
- it "provides intersection operators" do
89
- article.tag_names = ['portland', 'ruby']
90
- article.tag_names &= ['ruby', 'melbourne']
91
-
92
- article.tags.collect(&:name).should == ['ruby']
93
- end
94
-
95
78
  it "matches tag names ignoring case" do
96
79
  article.tag_names = ['portland']
97
80
  article.tag_names += ['Portland']
81
+ article.save!
98
82
 
99
83
  article.tags.collect(&:name).should == ['portland']
100
84
 
101
85
  article.tag_names << 'Portland'
86
+ article.save!
102
87
 
103
88
  article.tags.collect(&:name).should == ['portland']
104
89
  end
90
+
91
+ it "allows setting of tag names on unpersisted objects" do
92
+ article = Article.new :tag_names => ['melbourne', 'pancakes']
93
+ article.save!
94
+
95
+ article.tag_names.should == ['melbourne', 'pancakes']
96
+ end
105
97
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gutentag
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.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-07-25 00:00:00.000000000 Z
11
+ date: 2013-08-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -86,8 +86,8 @@ files:
86
86
  - lib/gutentag.rb
87
87
  - lib/gutentag/active_record.rb
88
88
  - lib/gutentag/engine.rb
89
+ - lib/gutentag/persistence.rb
89
90
  - lib/gutentag/tag_name.rb
90
- - lib/gutentag/tag_names.rb
91
91
  - spec/acceptance/tag_names_spec.rb
92
92
  - spec/acceptance/tags_spec.rb
93
93
  - spec/gutentag/tag_name_spec.rb
@@ -1,66 +0,0 @@
1
- class Gutentag::TagNames
2
- include Enumerable
3
-
4
- def self.new_with_names(taggable, names)
5
- new(taggable).replace names
6
- end
7
-
8
- def initialize(taggable)
9
- @taggable = taggable
10
- end
11
-
12
- def to_a
13
- taggable.tags.collect &:name
14
- end
15
-
16
- def +(array)
17
- normalised(array).each { |name| self.<< name }
18
-
19
- self
20
- end
21
-
22
- def -(array)
23
- normalised(array).each { |name| self.delete name }
24
-
25
- self
26
- end
27
-
28
- def <<(name)
29
- tag = Gutentag::Tag.find_or_create name
30
-
31
- taggable.tags << tag unless taggable.tags.include?(tag)
32
- end
33
-
34
- def |(array)
35
- to_a | normalised(array)
36
- end
37
-
38
- def &(array)
39
- to_a & normalised(array)
40
- end
41
-
42
- def clear
43
- taggable.tags.clear
44
- end
45
-
46
- def delete(name)
47
- taggable.tags.delete Gutentag::Tag.find_by_name(name)
48
- end
49
-
50
- def each(&block)
51
- to_a.each &block
52
- end
53
-
54
- def replace(names)
55
- clear
56
- self.+ names
57
- end
58
-
59
- private
60
-
61
- attr_reader :taggable
62
-
63
- def normalised(array)
64
- array.collect { |name| Gutentag::TagName.normalise(name) }
65
- end
66
- end