acts-as-taggable-on 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/acts_as_taggable_on/acts_as_taggable_on/collection.rb +54 -22
- data/spec/acts_as_taggable_on/taggable_spec.rb +15 -0
- data/spec/models.rb +1 -0
- metadata +3 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0.
|
1
|
+
2.0.1
|
@@ -53,39 +53,71 @@ module ActsAsTaggableOn::Taggable
|
|
53
53
|
def all_tag_counts(options = {})
|
54
54
|
options.assert_valid_keys :start_at, :end_at, :conditions, :at_least, :at_most, :order, :limit, :on, :id
|
55
55
|
|
56
|
-
|
57
|
-
|
56
|
+
scope = if ActiveRecord::VERSION::MAJOR >= 3
|
57
|
+
{}
|
58
|
+
else
|
59
|
+
scope(:find) || {}
|
60
|
+
end
|
58
61
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
+
## Generate conditions:
|
63
|
+
options[:conditions] = sanitize_sql(options[:conditions]) if options[:conditions]
|
64
|
+
|
65
|
+
start_at_conditions = sanitize_sql(["#{Tagging.table_name}.created_at >= ?", options.delete(:start_at)]) if options[:start_at]
|
66
|
+
end_at_conditions = sanitize_sql(["#{Tagging.table_name}.created_at <= ?", options.delete(:end_at)]) if options[:end_at]
|
67
|
+
|
68
|
+
taggable_conditions = sanitize_sql(["#{Tagging.table_name}.taggable_type = ?", base_class.name])
|
69
|
+
taggable_conditions << sanitize_sql([" AND #{Tagging.table_name}.taggable_id = ?", options.delete(:id)]) if options[:id]
|
62
70
|
|
63
71
|
conditions = [
|
64
|
-
|
65
|
-
taggable_id,
|
72
|
+
taggable_conditions,
|
66
73
|
options[:conditions],
|
67
|
-
|
68
|
-
|
69
|
-
|
74
|
+
scope[:conditions],
|
75
|
+
start_at_conditions,
|
76
|
+
end_at_conditions
|
77
|
+
].compact
|
78
|
+
|
79
|
+
## Generate joins:
|
80
|
+
tagging_join = "LEFT OUTER JOIN #{Tagging.table_name} ON #{Tag.table_name}.id = #{Tagging.table_name}.tag_id"
|
81
|
+
tagging_join << sanitize_sql([" AND #{Tagging.table_name}.context = ?", options.delete(:on).to_s]) if options[:on]
|
70
82
|
|
71
|
-
|
83
|
+
taggable_join = "INNER JOIN #{table_name} ON #{table_name}.#{primary_key} = #{Tagging.table_name}.taggable_id"
|
84
|
+
taggable_join << " AND #{table_name}.#{inheritance_column} = '#{name}'" unless descends_from_active_record? # Current model is STI descendant, so add type checking to the join condition
|
72
85
|
|
73
|
-
joins = [
|
74
|
-
|
75
|
-
|
86
|
+
joins = [
|
87
|
+
tagging_join,
|
88
|
+
taggable_join,
|
89
|
+
scope[:joins]
|
90
|
+
].compact
|
76
91
|
|
77
|
-
unless descends_from_active_record?
|
78
|
-
# Current model is STI descendant, so add type checking to the join condition
|
79
|
-
joins << " AND #{table_name}.#{inheritance_column} = '#{name}'"
|
80
|
-
end
|
81
92
|
|
93
|
+
## Generate scope:
|
94
|
+
scope = Tag.scoped(:select => "#{Tag.table_name}.*, COUNT(*) AS count").order(options[:order]).limit(options[:limit])
|
95
|
+
|
96
|
+
# Joins and conditions
|
97
|
+
joins.each { |join| scope = scope.joins(join) }
|
98
|
+
conditions.each { |condition| scope = scope.where(condition) }
|
99
|
+
|
100
|
+
# GROUP BY and HAVING clauses:
|
82
101
|
at_least = sanitize_sql(['COUNT(*) >= ?', options.delete(:at_least)]) if options[:at_least]
|
83
102
|
at_most = sanitize_sql(['COUNT(*) <= ?', options.delete(:at_most)]) if options[:at_most]
|
84
|
-
having = [at_least, at_most].compact.join(' AND ')
|
85
|
-
|
86
|
-
|
103
|
+
having = [at_least, at_most].compact.join(' AND ')
|
104
|
+
|
105
|
+
if ActiveRecord::VERSION::MAJOR >= 3
|
106
|
+
# Append the current scope to the scope, because we can't use scope(:find) in RoR 3.0 anymore:
|
107
|
+
scoped_select = "#{table_name}.#{primary_key}"
|
108
|
+
scope = scope.where("#{Tagging.table_name}.taggable_id IN(#{select(scoped_select).to_sql})")
|
109
|
+
|
110
|
+
# We have having() in RoR 3.0 so use it:
|
111
|
+
having = having.blank? ? "COUNT(*) > 0" : "COUNT(*) > 0 AND #{having}"
|
112
|
+
scope = scope.group(grouped_column_names_for(Tag)).having(having)
|
113
|
+
else
|
114
|
+
# Having is not available in 2.3.x:
|
115
|
+
group_by = "#{grouped_column_names_for(Tag)} HAVING COUNT(*) > 0"
|
116
|
+
group_by << " AND #{having}" unless having.blank?
|
117
|
+
scope = scope.group(group_by)
|
118
|
+
end
|
87
119
|
|
88
|
-
|
120
|
+
scope
|
89
121
|
end
|
90
122
|
end
|
91
123
|
|
@@ -144,6 +144,21 @@ describe "Taggable" do
|
|
144
144
|
TaggableModel.tagged_with("ruby").all_tag_counts.first.count.should == 3 # ruby
|
145
145
|
end
|
146
146
|
|
147
|
+
it 'should only return tag counts for the available scope' do
|
148
|
+
bob = TaggableModel.create(:name => "Bob", :tag_list => "ruby, rails, css")
|
149
|
+
frank = TaggableModel.create(:name => "Frank", :tag_list => "ruby, rails")
|
150
|
+
charlie = TaggableModel.create(:name => "Charlie", :skill_list => "ruby, java")
|
151
|
+
|
152
|
+
TaggableModel.tagged_with('rails').all_tag_counts.should have(3).items
|
153
|
+
TaggableModel.tagged_with('rails').all_tag_counts.any? { |tag| tag.name == 'java' }.should be_false
|
154
|
+
|
155
|
+
# Test specific join syntaxes:
|
156
|
+
frank.untaggable_models.create!
|
157
|
+
TaggableModel.tagged_with('rails').scoped(:joins => :untaggable_models).all_tag_counts.should have(2).items
|
158
|
+
TaggableModel.tagged_with('rails').scoped(:joins => { :untaggable_models => :taggable_model }).all_tag_counts.should have(2).items
|
159
|
+
TaggableModel.tagged_with('rails').scoped(:joins => [:untaggable_models]).all_tag_counts.should have(2).items
|
160
|
+
end
|
161
|
+
|
147
162
|
it "should be able to set a custom tag context list" do
|
148
163
|
bob = TaggableModel.create(:name => "Bob")
|
149
164
|
bob.set_tag_list_on(:rotors, "spinning, jumping")
|
data/spec/models.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 2
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 2.0.
|
8
|
+
- 1
|
9
|
+
version: 2.0.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Michael Bleigh
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-03-
|
17
|
+
date: 2010-03-30 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|