acts-as-taggable-on 2.0.0.rc1 → 2.0.0.rc2
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.
- data/README.rdoc +8 -8
- data/VERSION +1 -1
- data/lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb +3 -6
- data/lib/acts_as_taggable_on/acts_as_taggable_on/core.rb +41 -41
- data/lib/acts_as_taggable_on/acts_as_taggable_on/ownership.rb +24 -24
- data/spec/acts_as_taggable_on/taggable_spec.rb +3 -0
- metadata +3 -4
- data/lib/acts_as_taggable_on/acts_as_taggable_on/dirty.rb +0 -30
data/README.rdoc
CHANGED
@@ -52,7 +52,7 @@ To use it, add it to your Gemfile:
|
|
52
52
|
1. rails generate acts_as_taggable_on:migration
|
53
53
|
2. rake db:migrate
|
54
54
|
|
55
|
-
|
55
|
+
= Testing
|
56
56
|
|
57
57
|
Acts As Taggable On uses RSpec for its test coverage. Inside the plugin
|
58
58
|
directory, you can run the specs for RoR 3.0.0 with:
|
@@ -68,7 +68,7 @@ If you already have RSpec on your application, the specs will run while using:
|
|
68
68
|
rake spec:plugins
|
69
69
|
|
70
70
|
|
71
|
-
|
71
|
+
= Usage
|
72
72
|
|
73
73
|
class User < ActiveRecord::Base
|
74
74
|
acts_as_taggable_on :tags, :skills, :interests
|
@@ -87,7 +87,7 @@ rake spec:plugins
|
|
87
87
|
User.skill_counts # => [<Tag name="joking" count=2>,<Tag name="clowning" count=1>...]
|
88
88
|
@frankie.skill_counts
|
89
89
|
|
90
|
-
|
90
|
+
== Finding Tagged Objects
|
91
91
|
|
92
92
|
Acts As Taggable On utilizes named_scopes to create an association for tags.
|
93
93
|
This way you can mix and match to filter down your results, and it also improves
|
@@ -107,7 +107,7 @@ compatibility with the will_paginate gem:
|
|
107
107
|
# Find a user with any of the tags:
|
108
108
|
User.tagged_with(["awesome", "cool"], :any => true)
|
109
109
|
|
110
|
-
|
110
|
+
== Relationships
|
111
111
|
|
112
112
|
You can find objects of the same type based on similar tags on certain contexts.
|
113
113
|
Also, objects will be returned in descending order based on the total number of
|
@@ -126,7 +126,7 @@ matched tags.
|
|
126
126
|
@bobby.find_related_skills # => [<User name="Tom">]
|
127
127
|
@frankie.find_related_skills # => [<User name="Tom">]
|
128
128
|
|
129
|
-
|
129
|
+
== Dynamic Tag Contexts
|
130
130
|
|
131
131
|
In addition to the generated tag contexts in the definition, it is also possible
|
132
132
|
to allow for dynamic tag contexts (this could be user generated tag contexts!)
|
@@ -139,7 +139,7 @@ to allow for dynamic tag contexts (this could be user generated tag contexts!)
|
|
139
139
|
@user.tag_counts_on(:customs)
|
140
140
|
User.find_tagged_with("same", :on => :customs) # => [@user]
|
141
141
|
|
142
|
-
|
142
|
+
== Tag Ownership
|
143
143
|
|
144
144
|
Tags can have owners:
|
145
145
|
|
@@ -156,7 +156,7 @@ Tags can have owners:
|
|
156
156
|
@some_user.owned_tags
|
157
157
|
@some_photo.locations_from(@some_user)
|
158
158
|
|
159
|
-
|
159
|
+
== Tag cloud calculations
|
160
160
|
|
161
161
|
To construct tag clouds, the frequency of each tag needs to be calculated.
|
162
162
|
Because we specified +acts_as_taggable_on+ on the <tt>User</tt> class, we can
|
@@ -196,7 +196,7 @@ CSS:
|
|
196
196
|
.css3 { font-size: 1.4em; }
|
197
197
|
.css4 { font-size: 1.6em; }
|
198
198
|
|
199
|
-
|
199
|
+
= Contributors
|
200
200
|
|
201
201
|
* TomEric (i76) - Maintainer
|
202
202
|
* Michael Bleigh - Original Author
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0.0.
|
1
|
+
2.0.0.rc2
|
@@ -35,12 +35,7 @@ module ActsAsTaggableOn::Taggable
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
module InstanceMethods
|
39
|
-
def tag_list_cache_set_on(context)
|
40
|
-
variable_name = "@#{context.to_s.singularize}_list"
|
41
|
-
!instance_variable_get(variable_name).nil?
|
42
|
-
end
|
43
|
-
|
38
|
+
module InstanceMethods
|
44
39
|
def save_cached_tag_list
|
45
40
|
tag_types.map(&:to_s).each do |tag_type|
|
46
41
|
if self.class.send("caching_#{tag_type.singularize}_list?")
|
@@ -50,6 +45,8 @@ module ActsAsTaggableOn::Taggable
|
|
50
45
|
end
|
51
46
|
end
|
52
47
|
end
|
48
|
+
|
49
|
+
true
|
53
50
|
end
|
54
51
|
end
|
55
52
|
end
|
@@ -14,27 +14,28 @@ module ActsAsTaggableOn::Taggable
|
|
14
14
|
|
15
15
|
module ClassMethods
|
16
16
|
def initialize_acts_as_taggable_on_core
|
17
|
-
tag_types.map(&:to_s).each do |
|
18
|
-
|
19
|
-
|
17
|
+
tag_types.map(&:to_s).each do |tags_type|
|
18
|
+
tag_type = tags_type.to_s.singularize
|
19
|
+
context_taggings = "#{tag_type}_taggings".to_sym
|
20
|
+
context_tags = tags_type.to_sym
|
20
21
|
|
21
22
|
class_eval do
|
22
23
|
has_many context_taggings, :as => :taggable, :dependent => :destroy, :include => :tag, :class_name => "Tagging",
|
23
|
-
:conditions => ['#{Tagging.table_name}.tagger_id IS NULL AND #{Tagging.table_name}.context = ?',
|
24
|
+
:conditions => ['#{Tagging.table_name}.tagger_id IS NULL AND #{Tagging.table_name}.context = ?', tags_type]
|
24
25
|
has_many context_tags, :through => context_taggings, :source => :tag
|
25
26
|
end
|
26
27
|
|
27
28
|
class_eval %(
|
28
|
-
def #{tag_type
|
29
|
-
tag_list_on('#{
|
29
|
+
def #{tag_type}_list
|
30
|
+
tag_list_on('#{tags_type}')
|
30
31
|
end
|
31
32
|
|
32
|
-
def #{tag_type
|
33
|
-
set_tag_list_on('#{
|
33
|
+
def #{tag_type}_list=(new_tags)
|
34
|
+
set_tag_list_on('#{tags_type}', new_tags)
|
34
35
|
end
|
35
36
|
|
36
|
-
def all_#{
|
37
|
-
all_tags_list_on('#{
|
37
|
+
def all_#{tags_type}_list
|
38
|
+
all_tags_list_on('#{tags_type}')
|
38
39
|
end
|
39
40
|
)
|
40
41
|
end
|
@@ -129,6 +130,11 @@ module ActsAsTaggableOn::Taggable
|
|
129
130
|
self["cached_#{context.to_s.singularize}_list"]
|
130
131
|
end
|
131
132
|
|
133
|
+
def tag_list_cache_set_on(context)
|
134
|
+
variable_name = "@#{context.to_s.singularize}_list"
|
135
|
+
!instance_variable_get(variable_name).nil?
|
136
|
+
end
|
137
|
+
|
132
138
|
def tag_list_cache_on(context)
|
133
139
|
variable_name = "@#{context.to_s.singularize}_list"
|
134
140
|
instance_variable_get(variable_name) || instance_variable_set(variable_name, TagList.new(tags_on(context).map(&:name)))
|
@@ -156,18 +162,12 @@ module ActsAsTaggableOn::Taggable
|
|
156
162
|
##
|
157
163
|
# Returns all tags that are not owned of a given context
|
158
164
|
def tags_on(context)
|
159
|
-
|
160
|
-
# If the association is available, use it:
|
161
|
-
send(context).all
|
162
|
-
else
|
163
|
-
# If the association is not available, query it the old fashioned way
|
164
|
-
base_tags.where(["#{Tagging.table_name}.context = ? AND #{Tagging.table_name}.tagger_id IS NULL", context.to_s]).all
|
165
|
-
end
|
165
|
+
base_tags.where(["#{Tagging.table_name}.context = ? AND #{Tagging.table_name}.tagger_id IS NULL", context.to_s]).all
|
166
166
|
end
|
167
167
|
|
168
168
|
def set_tag_list_on(context, new_list)
|
169
169
|
add_custom_context(context)
|
170
|
-
|
170
|
+
|
171
171
|
variable_name = "@#{context.to_s.singularize}_list"
|
172
172
|
instance_variable_set(variable_name, TagList.from(new_list))
|
173
173
|
end
|
@@ -186,30 +186,30 @@ module ActsAsTaggableOn::Taggable
|
|
186
186
|
end
|
187
187
|
|
188
188
|
def save_tags
|
189
|
-
|
190
|
-
|
191
|
-
tag_list = tag_list_cache_on(context).uniq
|
192
|
-
|
193
|
-
# Find existing tags or create non-existing tags:
|
194
|
-
tag_list = Tag.find_or_create_all_with_like_by_name(tag_list)
|
195
|
-
|
196
|
-
current_tags = tags_on(context)
|
197
|
-
old_tags = current_tags - tag_list
|
198
|
-
new_tags = tag_list - current_tags
|
199
|
-
|
200
|
-
# Find taggings to remove:
|
201
|
-
old_taggings = taggings.where(:tagger_type => nil, :tagger_id => nil,
|
202
|
-
:context => context.to_s, :tag_id => old_tags).all
|
203
|
-
|
204
|
-
if old_taggings.present?
|
205
|
-
# Destroy old taggings:
|
206
|
-
Tagging.destroy_all :id => old_taggings.map(&:id)
|
207
|
-
end
|
189
|
+
tagging_contexts.each do |context|
|
190
|
+
next unless tag_list_cache_set_on(context)
|
208
191
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
192
|
+
tag_list = tag_list_cache_on(context).uniq
|
193
|
+
|
194
|
+
# Find existing tags or create non-existing tags:
|
195
|
+
tag_list = Tag.find_or_create_all_with_like_by_name(tag_list)
|
196
|
+
|
197
|
+
current_tags = tags_on(context)
|
198
|
+
old_tags = current_tags - tag_list
|
199
|
+
new_tags = tag_list - current_tags
|
200
|
+
|
201
|
+
# Find taggings to remove:
|
202
|
+
old_taggings = taggings.where(:tagger_type => nil, :tagger_id => nil,
|
203
|
+
:context => context.to_s, :tag_id => old_tags).all
|
204
|
+
|
205
|
+
if old_taggings.present?
|
206
|
+
# Destroy old taggings:
|
207
|
+
Tagging.destroy_all :id => old_taggings.map(&:id)
|
208
|
+
end
|
209
|
+
|
210
|
+
# Create new taggings:
|
211
|
+
new_tags.each do |tag|
|
212
|
+
taggings.create!(:tag_id => tag.id, :context => context.to_s, :taggable => self)
|
213
213
|
end
|
214
214
|
end
|
215
215
|
|
@@ -67,34 +67,34 @@ module ActsAsTaggableOn::Taggable
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def save_owned_tags
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
tag_list = Tag.find_or_create_all_with_like_by_name(tag_list.uniq)
|
75
|
-
|
76
|
-
owned_tags = owner_tags_on(owner, context)
|
77
|
-
old_tags = owned_tags - tag_list
|
78
|
-
new_tags = tag_list - owned_tags
|
79
|
-
|
80
|
-
# Find all taggings that belong to the taggable (self), are owned by the owner,
|
81
|
-
# have the correct context, and are removed from the list.
|
82
|
-
old_taggings = Tagging.where(:taggable_id => id, :taggable_type => self.class.base_class.to_s,
|
83
|
-
:tagger_type => owner.class.to_s, :tagger_id => owner.id,
|
84
|
-
:tag_id => old_tags, :context => context).all
|
85
|
-
|
86
|
-
if old_taggings.present?
|
87
|
-
# Destroy old taggings:
|
88
|
-
Tagging.destroy_all(:id => old_taggings.map(&:id))
|
89
|
-
end
|
70
|
+
tagging_contexts.each do |context|
|
71
|
+
cached_owned_tag_list_on(context).each do |owner, tag_list|
|
72
|
+
# Find existing tags or create non-existing tags:
|
73
|
+
tag_list = Tag.find_or_create_all_with_like_by_name(tag_list.uniq)
|
90
74
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
75
|
+
owned_tags = owner_tags_on(owner, context)
|
76
|
+
old_tags = owned_tags - tag_list
|
77
|
+
new_tags = tag_list - owned_tags
|
78
|
+
|
79
|
+
# Find all taggings that belong to the taggable (self), are owned by the owner,
|
80
|
+
# have the correct context, and are removed from the list.
|
81
|
+
old_taggings = Tagging.where(:taggable_id => id, :taggable_type => self.class.base_class.to_s,
|
82
|
+
:tagger_type => owner.class.to_s, :tagger_id => owner.id,
|
83
|
+
:tag_id => old_tags, :context => context).all
|
84
|
+
|
85
|
+
if old_taggings.present?
|
86
|
+
# Destroy old taggings:
|
87
|
+
Tagging.destroy_all(:id => old_taggings.map(&:id))
|
88
|
+
end
|
89
|
+
|
90
|
+
# Create new taggings:
|
91
|
+
new_tags.each do |tag|
|
92
|
+
taggings.create!(:tag_id => tag.id, :context => context.to_s, :tagger => owner, :taggable => self)
|
95
93
|
end
|
96
94
|
end
|
97
95
|
end
|
96
|
+
|
97
|
+
true
|
98
98
|
end
|
99
99
|
end
|
100
100
|
end
|
metadata
CHANGED
@@ -6,8 +6,8 @@ version: !ruby/object:Gem::Version
|
|
6
6
|
- 2
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 2.0.0.
|
9
|
+
- rc2
|
10
|
+
version: 2.0.0.rc2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Michael Bleigh
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-03-
|
18
|
+
date: 2010-03-28 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -41,7 +41,6 @@ files:
|
|
41
41
|
- lib/acts_as_taggable_on/acts_as_taggable_on/cache.rb
|
42
42
|
- lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb
|
43
43
|
- lib/acts_as_taggable_on/acts_as_taggable_on/core.rb
|
44
|
-
- lib/acts_as_taggable_on/acts_as_taggable_on/dirty.rb
|
45
44
|
- lib/acts_as_taggable_on/acts_as_taggable_on/ownership.rb
|
46
45
|
- lib/acts_as_taggable_on/acts_as_taggable_on/related.rb
|
47
46
|
- lib/acts_as_taggable_on/acts_as_tagger.rb
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# WIP: dirty attributes support for tags
|
2
|
-
module ActsAsTaggableOn::Taggable
|
3
|
-
module Dirty
|
4
|
-
def self.included(base)
|
5
|
-
include ActsAsTaggableOn::Taggable::Dirty::InstanceMethods
|
6
|
-
|
7
|
-
base.tag_types.map(&:to_s).each do |tag_type|
|
8
|
-
base.class_eval %(
|
9
|
-
def #{tag_type.singularize}_list_changed?
|
10
|
-
tag_list_changed_on?('#{tag_type}')
|
11
|
-
tag_list_on('#{tag_type}')
|
12
|
-
end
|
13
|
-
|
14
|
-
def #{tag_type.singularize}_list=(new_tags)
|
15
|
-
change_tag_list_on('#{tag_type}', new_tags)
|
16
|
-
super(new_tags)
|
17
|
-
end
|
18
|
-
)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
module InstanceMethods
|
23
|
-
def tag_list_changed_on?(context)
|
24
|
-
end
|
25
|
-
|
26
|
-
def change_tag_list_on(context, new_tags)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|