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 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