tagalong 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +7 -0
- data/README.md +70 -31
- data/Rakefile +3 -0
- data/lib/tagalong/tagger.rb +7 -0
- data/lib/tagalong/version.rb +1 -1
- data/spec/database.yml +2 -1
- data/spec/lib/tagalong/tagger_spec.rb +22 -0
- data/tagalong.gemspec +1 -0
- metadata +20 -8
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,14 +1,19 @@
|
|
1
1
|
# Tagalong
|
2
2
|
|
3
|
-
|
3
|
+
[![Build Status](https://secure.travis-ci.org/cyphactor/tagalong.png?branch=master)](http://travis-ci.org/cyphactor/tagalong)
|
4
4
|
|
5
|
-
|
5
|
+
[Tagalong](http://github.com/cyphactor/tagalong) is a Rails tagging plugin that is intended to be clean, efficient, and simple. I have tried hard to keep the API slim and intelligable in terms of Object Oriented Programming. I focused heavily on this as I feel most other Rails tagging plugins seriously neglect OO in their APIs.
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
The other key differentiation between [Tagalong](http://github.com/cyphactor/tagalong) and other tagging libraries is the relational database structure behind the scenes. This database structure allows [Tagalong](http://github.com/cyphactor/tagalong) to provide not only an Object Oriented API, but also a set of features that help differentiate it from other Rails tagging plugins.
|
8
|
+
|
9
|
+
## Feature Overview
|
10
|
+
|
11
|
+
* clean Object Oriented API
|
12
|
+
* does NOT require saving of the model when tagging/untagging
|
9
13
|
* keeps history of tags Taggers have used
|
10
14
|
* allows defining multiple Taggers and Taggables
|
11
|
-
* tracks number of times tags are used
|
15
|
+
* tracks the number of times tags are used
|
16
|
+
* returns tag lists in alphabetical order (imporant for UI)
|
12
17
|
|
13
18
|
## Installation
|
14
19
|
|
@@ -20,23 +25,39 @@ And then execute:
|
|
20
25
|
|
21
26
|
$ bundle
|
22
27
|
|
23
|
-
Or install it
|
28
|
+
Or manually install it:
|
24
29
|
|
25
30
|
$ gem install tagalong
|
26
31
|
|
32
|
+
## API Concepts
|
33
|
+
|
34
|
+
There are three major concepts that one should understand before reading the documentation for the API, the Tag, Tagger, and Taggable.
|
35
|
+
|
36
|
+
### Tag
|
37
|
+
|
38
|
+
A Tag in the [Tagalong](http://github.com/cyphactor/tagalong) API is represented by a string. Conceptually it is simply a textual label that is associated with a Taggable and a Tagger.
|
39
|
+
|
40
|
+
### Tagger
|
41
|
+
|
42
|
+
A Tagger is an object that will be performing the action of applying a tag to a Taggable. In most Rails apps this is the a User object.
|
43
|
+
|
44
|
+
### Taggable
|
45
|
+
|
46
|
+
A Taggable is an object that will be having the tags applied to it. In a Rails app this could be a Task object, Contact object, or any type of object that you want to be able to tag.
|
47
|
+
|
27
48
|
## Usage
|
28
49
|
|
29
50
|
### Migration Setup
|
30
51
|
|
31
|
-
In order to use
|
52
|
+
In order to use [Tagalong](http://github.com/cyphactor/tagalong), generate the proper migrations so that the tags can be stored in the database. This can be done with the following command:
|
32
53
|
|
33
54
|
rails generate tagalong:migration
|
34
55
|
|
35
|
-
The above will generate the migration and place it appropriately in the db/migrate
|
56
|
+
The above will generate the migration and place it appropriately in the `db/migrate/` project path.
|
36
57
|
|
37
58
|
### Declaring Taggers and Taggables
|
38
59
|
|
39
|
-
|
60
|
+
It is necessary to declare at least one Tagger and Taggable in addition to generating and running the migrations. This is done as follows:
|
40
61
|
|
41
62
|
class Contact < ActiveRecord::Base
|
42
63
|
tagalong_taggable
|
@@ -46,58 +67,76 @@ In order to use `tagalong` you need to first declare at least one Tagger and at
|
|
46
67
|
tagalong_tagger
|
47
68
|
end
|
48
69
|
|
49
|
-
|
70
|
+
Once Taggers and Taggables are declared, they can be used in numerous ways as outlined below.
|
50
71
|
|
51
|
-
|
72
|
+
### Tagging
|
73
|
+
|
74
|
+
To tag, call the `tag` method on a Tagger object and hand it a persisted Taggable object with the given label that you want to apply.
|
52
75
|
|
53
76
|
@user.tag(@contact, "sometag")
|
54
77
|
|
55
|
-
###
|
78
|
+
### Untagging
|
56
79
|
|
57
|
-
To untag
|
80
|
+
To untag, call the `untag` method on a Tagger object and hand it a persisted Taggable object with the given label that you want to untag.
|
58
81
|
|
59
82
|
@user.untag(@contact, "sometag")
|
60
83
|
|
61
|
-
###
|
62
|
-
|
63
|
-
You can get the list of tags for either a Tagger or a Taggable.
|
84
|
+
### Deleting
|
64
85
|
|
65
|
-
|
86
|
+
To delete a tag, call the `delete_tag` method on a Tagger object and hand it the label of the tag you want to delete. This will remove the tag from the Tagger, as well as all Taggables that might be using it.
|
66
87
|
|
67
|
-
@user.
|
68
|
-
# => ['some_tag', 'another_tag', 'woot_tag']
|
88
|
+
@user.delete_tag("sometag")
|
69
89
|
|
70
|
-
|
90
|
+
### List Tagger tags
|
71
91
|
|
72
|
-
|
73
|
-
# => ['some_tag', 'woot_tag']
|
92
|
+
To list Tagger tags, call the `tags` method on a Tagger object. This will return an array of all tags that Tagger has ever used in ascending alphabetical order.
|
74
93
|
|
75
|
-
|
94
|
+
@user.tags
|
95
|
+
# => ['another_tag', 'some_tag', 'woot_tag']
|
76
96
|
|
77
|
-
### List tags with usage info
|
97
|
+
### List Tagger tags with usage info
|
78
98
|
|
79
|
-
|
99
|
+
To list Tagger tags with usage info, call the `tags` method on a Tagger object passing in a Taggable object. This will return a list of hash objects containing the tag ( **:tag** ), a boolean representing if the Taggable passed in is currently tagged with that tag ( **:used** ), and the number of references of that tag by the Tagger ( **:number_of_references** ). The resulting list of hashes is ordered by tag in ascending alphabetical order.
|
80
100
|
|
81
101
|
@user.tags(@contact)
|
82
102
|
# => [
|
103
|
+
{ tag: 'another_tag', :used => false, :number_of_references => 42 },
|
83
104
|
{ tag: 'some_tag', :used => true, :number_of_references => 23 },
|
84
|
-
{ tag: '
|
105
|
+
{ tag: 'woot_tag', :used => true, :number_of_references => 2 }
|
85
106
|
]
|
86
107
|
|
87
|
-
### List
|
108
|
+
### List Taggable tags
|
109
|
+
|
110
|
+
To list Taggable tags, call the `tags` method on a Taggable object. This will return an array of all tags that Taggable is currently tagged with in ascending alphabetical order.
|
111
|
+
|
112
|
+
@contact.tags
|
113
|
+
# => ['some_tag', 'woot_tag']
|
88
114
|
|
89
|
-
|
115
|
+
### List Taggables that have a tag
|
116
|
+
|
117
|
+
To list Taggables that have a tag, call the `taggables_with` method on a Tagger object as follows. This will return an array of Taggable objects that are currently tagged with the given tag.
|
90
118
|
|
91
119
|
@user.taggables_with('some_tag')
|
92
|
-
# => [
|
120
|
+
# => [Contact Object, Contact Object]
|
121
|
+
|
122
|
+
### Check if Taggable is tagged with a tag
|
123
|
+
|
124
|
+
To check if a Taggable is tagged with a tag, call the `tagged_with?` method on a Taggable object as follows. This will return `true` in the case that the Taggable IS currently tagged with the given tag, and `false` in the case where the Taggable is NOT currently tagged with the given tag.
|
125
|
+
|
126
|
+
@contact.tagged_with?('some_tag')
|
127
|
+
# => true
|
93
128
|
|
94
129
|
## Credits
|
95
130
|
|
96
|
-
I just wanted to thank all of the other open source Rails tagging plugins out there. Especially, acts-as-taggable-on, I learned a lot from you all.
|
131
|
+
I just wanted to thank all of the other open source Rails tagging plugins out there. Especially, [acts-as-taggable-on](http://github.com/mbleigh/acts-as-taggable-on), [is_taggable](http://github.com/jamesgolick/is_taggable), and [rocket_tag](http://github.com/bradphelan/rocket_tag). I learned a lot from you all.
|
132
|
+
|
133
|
+
I also want to thank [RealPractice, Inc.](http://realpractice.com) for donating some developer hours to the project as well as being our initial user.
|
134
|
+
|
135
|
+
Beyond that I want to specifically thank [@cyoungberg](http://github.com/cyoungberg) and [@russCloak](http://github.com/russCloak) for discussing the API decissions with me. It definitely helped having you guys as a sounding board.
|
97
136
|
|
98
137
|
## Contributing
|
99
138
|
|
100
|
-
If you are interested in contributing code please follow the process below and
|
139
|
+
If you are interested in contributing code please follow the process below and include tests. Also, please fill out issues on our GitHub [issues](http://github.com/cyphactor/tagalong/issues) page if you have discovered a bug or simply want to request a feature.
|
101
140
|
|
102
141
|
1. Fork it
|
103
142
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
data/Rakefile
CHANGED
data/lib/tagalong/tagger.rb
CHANGED
@@ -26,6 +26,13 @@ module Tagalong
|
|
26
26
|
tag_manager.remove_tag(tag_name)
|
27
27
|
end
|
28
28
|
|
29
|
+
def delete_tag(tag_name)
|
30
|
+
tag = tagalong_tags.find_by_name(tag_name)
|
31
|
+
if tag.present?
|
32
|
+
tag.destroy
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
29
36
|
def tags(taggable = nil)
|
30
37
|
if taggable == nil
|
31
38
|
return self.tagalong_tags.order("name ASC").map { |r| r.name }
|
data/lib/tagalong/version.rb
CHANGED
data/spec/database.yml
CHANGED
@@ -25,6 +25,28 @@ describe "Tagger" do
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
describe "#delete_tag" do
|
29
|
+
before(:each) do
|
30
|
+
@user.tag(@contact, "tag1")
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should disassociate the tag that belongs to it" do
|
34
|
+
@user.delete_tag('tag1')
|
35
|
+
@user.tags.should_not include("tag1")
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should destroy the tag record from the db" do
|
39
|
+
@user.delete_tag('tag1')
|
40
|
+
Tagalong::TagalongTag.find_by_name('tag1').should_not be_present
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should not destroy tags it does not have" do
|
44
|
+
Tagalong::TagalongTag.create(:tagger_type => 'FakeTagger', :tagger_id => 1, :name => 'badTag')
|
45
|
+
@user.delete_tag('badTag')
|
46
|
+
Tagalong::TagalongTag.find_by_name('badTag').should be_present
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
28
50
|
describe "#tags" do
|
29
51
|
context "without a taggable" do
|
30
52
|
it "returns list of tags the tagger has used" do
|
data/tagalong.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tagalong
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05-
|
12
|
+
date: 2012-05-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
16
|
-
requirement: &
|
16
|
+
requirement: &70195968616540 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70195968616540
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: sqlite3
|
27
|
-
requirement: &
|
27
|
+
requirement: &70195968616100 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70195968616100
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rspec
|
38
|
-
requirement: &
|
38
|
+
requirement: &70195968615680 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,7 +43,18 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70195968615680
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
requirement: &70195968615240 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70195968615240
|
47
58
|
description: A Rails tagging plugin that makes sense.
|
48
59
|
email:
|
49
60
|
- cyphactor@gmail.com
|
@@ -53,6 +64,7 @@ extra_rdoc_files: []
|
|
53
64
|
files:
|
54
65
|
- .gitignore
|
55
66
|
- .rvmrc
|
67
|
+
- .travis.yml
|
56
68
|
- Gemfile
|
57
69
|
- LICENSE
|
58
70
|
- README.md
|