acts-as-taggable-on 2.0.0 → 2.0.1

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/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.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
- start_at = sanitize_sql(["#{Tagging.table_name}.created_at >= ?", options.delete(:start_at)]) if options[:start_at]
57
- end_at = sanitize_sql(["#{Tagging.table_name}.created_at <= ?", options.delete(:end_at)]) if options[:end_at]
56
+ scope = if ActiveRecord::VERSION::MAJOR >= 3
57
+ {}
58
+ else
59
+ scope(:find) || {}
60
+ end
58
61
 
59
- taggable_type = sanitize_sql(["#{Tagging.table_name}.taggable_type = ?", base_class.name])
60
- taggable_id = sanitize_sql(["#{Tagging.table_name}.taggable_id = ?", options.delete(:id)]) if options[:id]
61
- options[:conditions] = sanitize_sql(options[:conditions]) if options[:conditions]
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
- taggable_type,
65
- taggable_id,
72
+ taggable_conditions,
66
73
  options[:conditions],
67
- start_at,
68
- end_at
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
- conditions = conditions.compact.join(' AND ')
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 = ["LEFT OUTER JOIN #{Tagging.table_name} ON #{Tag.table_name}.id = #{Tagging.table_name}.tag_id"]
74
- joins << sanitize_sql(["AND #{Tagging.table_name}.context = ?",options.delete(:on).to_s]) unless options[:on].nil?
75
- joins << " INNER JOIN #{table_name} ON #{table_name}.#{primary_key} = #{Tagging.table_name}.taggable_id"
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
- group_by = "#{grouped_column_names_for(Tag)} HAVING COUNT(*) > 0"
86
- group_by << " AND #{having}" unless having.blank?
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
- Tag.select("#{Tag.table_name}.*, COUNT(*) AS count").joins(joins.join(" ")).where(conditions).group(group_by).limit(options[:limit]).order(options[:order])
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")
@@ -27,4 +27,5 @@ class TaggableUser < ActiveRecord::Base
27
27
  end
28
28
 
29
29
  class UntaggableModel < ActiveRecord::Base
30
+ belongs_to :taggable_model
30
31
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 2
7
7
  - 0
8
- - 0
9
- version: 2.0.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-28 00:00:00 +01:00
17
+ date: 2010-03-30 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies: []
20
20