tagtools 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ == TagTools 0.0.3
2
+ * fixed a particularly nasty bug with tag queries on user-scoped tags
3
+ * added a mixin for tag classes
4
+ * improved the unit tests
1
5
  == TagTools 0.0.2
2
6
  * fixed a bug in delete_records for user tag collections
3
7
  * added include? method to all tag collections
@@ -21,7 +21,7 @@
21
21
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  #++
23
23
 
24
- TAG_TOOLS_VERSION = "0.0.2"
24
+ TAG_TOOLS_VERSION = "0.0.3"
25
25
 
26
26
  $:.unshift(File.dirname(__FILE__))
27
27
  $:.unshift(File.dirname(__FILE__) + "/../../activerecord/lib")
@@ -539,6 +539,23 @@ module ActiveRecord #:nodoc:
539
539
  undecorated_table_name(tag_class.name),
540
540
  undecorated_table_name(user_class.name),
541
541
  undecorated_table_name(item_class.name))
542
+
543
+ association_hash = {
544
+ :tag_class => tag_class,
545
+ :tag_foreign_key => tag_foreign_key,
546
+ :item_class => item_class,
547
+ :item_foreign_key => item_foreign_key,
548
+ :user_class => user_class,
549
+ :user_foreign_key => user_foreign_key,
550
+ :join_table => options[:join_table]
551
+ }
552
+
553
+ if tag_class.instance_variable_get("@tagged_classes").nil?
554
+ tag_class.instance_variable_set("@tagged_classes", [])
555
+ end
556
+ tagged_classes =
557
+ tag_class.instance_variable_get("@tagged_classes")
558
+ tagged_classes << association_hash
542
559
 
543
560
  # Create the two collections
544
561
  define_method(options[:collection]) do |*params|
@@ -579,8 +596,15 @@ module ActiveRecord #:nodoc:
579
596
  singleton_class.module_eval do
580
597
  define_method(:tag_query) do |*params|
581
598
  query_options = params.first unless params.empty?
599
+ unless query_options.kind_of? Hash
600
+ raise "The first parameter must be a hash."
601
+ end
582
602
  validate_options([:with_any_tags, :with_all_tags,
583
603
  :without_tags, :user_id], query_options.keys)
604
+ if query_options.size == 0
605
+ raise "You must supply either the with_any_tags option, " +
606
+ "the with_all_tags option, or both."
607
+ end
584
608
  with_any_tags = query_options[:with_any_tags]
585
609
  unless with_any_tags.nil?
586
610
  with_any_tags.collect! { |tag| tag.to_s }
@@ -616,57 +640,58 @@ module ActiveRecord #:nodoc:
616
640
 
617
641
  with_all_tags_results = nil
618
642
  if with_all_tags != nil && with_all_tags.size > 0
619
- with_all_tags_query_thread = Thread.new do
620
- tag_name_condition = "#{tag_class.table_name}.name = '" +
621
- with_all_tags.join(
622
- "\' OR #{tag_class.table_name}.name=\'") + "'"
623
- with_all_tags_sql = <<-SQL
624
- SELECT #{item_class.table_name}.*
625
- FROM #{options[:join_table]}, #{item_class.table_name},
626
- #{tag_class.table_name}
627
- WHERE #{options[:join_table]}.#{tag_foreign_key} =
628
- #{tag_class.table_name}.#{tag_class.primary_key}
629
- AND (#{tag_name_condition})
630
- AND #{item_class.table_name}.#{item_class.primary_key} =
631
- #{options[:join_table]}.#{item_foreign_key}
632
- #{tagging_user_id_string}
633
- GROUP BY #{group_by_string}
634
- HAVING COUNT(
635
- #{item_class.table_name}.#{item_class.primary_key}) =
636
- #{with_all_tags.size}
637
- SQL
638
- with_all_tags_results =
639
- item_class.find_by_sql(with_all_tags_sql)
643
+ tag_name_condition = "#{tag_class.table_name}.name = '" +
644
+ with_all_tags.join(
645
+ "\' OR #{tag_class.table_name}.name=\'") + "'"
646
+ with_all_tags_sql = <<-SQL
647
+ SELECT #{item_class.table_name}.*
648
+ FROM #{options[:join_table]}, #{item_class.table_name},
649
+ #{tag_class.table_name}
650
+ WHERE #{options[:join_table]}.#{tag_foreign_key} =
651
+ #{tag_class.table_name}.#{tag_class.primary_key}
652
+ AND (#{tag_name_condition})
653
+ AND #{item_class.table_name}.#{item_class.primary_key} =
654
+ #{options[:join_table]}.#{item_foreign_key}
655
+ #{tagging_user_id_string}
656
+ GROUP BY #{group_by_string}
657
+ HAVING COUNT(
658
+ #{item_class.table_name}.#{item_class.primary_key}) >=
659
+ #{with_all_tags.size}
660
+ SQL
661
+ with_all_tags_results =
662
+ item_class.find_by_sql(with_all_tags_sql)
663
+ if tagging_user_id.nil?
664
+ for result in with_all_tags_results
665
+ result_tags = result.tags.map do |tag|
666
+ tag.name
667
+ end
668
+ if (result_tags & with_all_tags).size != with_all_tags.size
669
+ # Reject result
670
+ with_all_tags_results.delete(result)
671
+ end
672
+ end
640
673
  end
641
674
  end
642
675
 
643
676
  with_any_tags_results = nil
644
677
  if with_any_tags != nil && with_any_tags.size > 0
645
- with_any_tags_query_thread = Thread.new do
646
- with_any_tags_sql = <<-SQL
647
- SELECT #{item_class.table_name}.*
648
- FROM #{options[:join_table]}, #{item_class.table_name},
649
- #{tag_class.table_name}
650
- WHERE #{tag_class.table_name}.name
651
- IN ('#{with_any_tags.join('\', \'')}')
652
- AND #{tag_class.table_name}.#{tag_class.primary_key} =
653
- #{options[:join_table]}.#{tag_foreign_key}
654
- AND #{item_class.table_name}.#{item_class.primary_key} =
655
- #{options[:join_table]}.#{item_foreign_key}
656
- #{tagging_user_id_string}
657
- GROUP BY #{group_by_string}
658
- SQL
659
- with_any_tags_results =
660
- item_class.find_by_sql(with_any_tags_sql)
661
- end
678
+ with_any_tags_sql = <<-SQL
679
+ SELECT #{item_class.table_name}.*
680
+ FROM #{options[:join_table]}, #{item_class.table_name},
681
+ #{tag_class.table_name}
682
+ WHERE #{tag_class.table_name}.name
683
+ IN ('#{with_any_tags.join('\', \'')}')
684
+ AND #{tag_class.table_name}.#{tag_class.primary_key} =
685
+ #{options[:join_table]}.#{tag_foreign_key}
686
+ AND #{item_class.table_name}.#{item_class.primary_key} =
687
+ #{options[:join_table]}.#{item_foreign_key}
688
+ #{tagging_user_id_string}
689
+ GROUP BY #{group_by_string}
690
+ SQL
691
+ with_any_tags_results =
692
+ item_class.find_by_sql(with_any_tags_sql)
662
693
  end
663
694
 
664
- if with_all_tags != nil && with_all_tags.size > 0
665
- with_all_tags_query_thread.join
666
- end
667
- if with_any_tags != nil && with_any_tags.size > 0
668
- with_any_tags_query_thread.join
669
- end
670
695
  if with_any_tags_results != nil &&
671
696
  with_any_tags_results.size > 0 &&
672
697
  with_all_tags_results != nil &&
@@ -679,11 +704,19 @@ module ActiveRecord #:nodoc:
679
704
  with_all_tags_results.size > 0
680
705
  results = with_all_tags_results
681
706
  end
707
+
682
708
  if without_tags != nil && without_tags.size > 0
683
709
  for result in results
684
- if ((result.tags.map { |tag| tag.name }) &
685
- without_tags).size > 0
686
- results.delete(result)
710
+ if tagging_user_id.nil?
711
+ if ((result.tags.map { |tag| tag.name }) &
712
+ without_tags).size > 0
713
+ results.delete(result)
714
+ end
715
+ else
716
+ if ((result.user_tags(tagging_user_id).map { |tag| tag.name }) &
717
+ without_tags).size > 0
718
+ results.delete(result)
719
+ end
687
720
  end
688
721
  end
689
722
  end
@@ -780,6 +813,23 @@ module ActiveRecord #:nodoc:
780
813
  undecorated_table_name(tag_class.name),
781
814
  undecorated_table_name(item_class.name))
782
815
 
816
+ association_hash = {
817
+ :tag_class => tag_class,
818
+ :tag_foreign_key => tag_foreign_key,
819
+ :item_class => item_class,
820
+ :item_foreign_key => item_foreign_key,
821
+ :user_class => nil,
822
+ :user_foreign_key => nil,
823
+ :join_table => options[:join_table]
824
+ }
825
+
826
+ if tag_class.instance_variable_get("@tagged_classes").nil?
827
+ tag_class.instance_variable_set("@tagged_classes", [])
828
+ end
829
+ tagged_classes =
830
+ tag_class.instance_variable_get("@tagged_classes")
831
+ tagged_classes << association_hash
832
+
783
833
  define_method(options[:collection]) do |*params|
784
834
  force_reload = params.first unless params.empty?
785
835
  association = instance_variable_get(
@@ -799,8 +849,15 @@ module ActiveRecord #:nodoc:
799
849
  singleton_class.module_eval do
800
850
  define_method(:tag_query) do |*params|
801
851
  query_options = params.first unless params.empty?
852
+ unless query_options.kind_of? Hash
853
+ raise "The first parameter must be a hash."
854
+ end
802
855
  validate_options([:with_any_tags, :with_all_tags,
803
- :without_tags], query_options.keys)
856
+ :without_tags, :user_id], query_options.keys)
857
+ if query_options.size == 0
858
+ raise "You must supply either the with_any_tags option, " +
859
+ "the with_all_tags option, or both."
860
+ end
804
861
  with_any_tags = query_options[:with_any_tags]
805
862
  unless with_any_tags.nil?
806
863
  with_any_tags.collect! { |tag| tag.to_s }
@@ -829,55 +886,45 @@ module ActiveRecord #:nodoc:
829
886
 
830
887
  with_all_tags_results = nil
831
888
  if with_all_tags != nil && with_all_tags.size > 0
832
- with_all_tags_query_thread = Thread.new do
833
- tag_name_condition = "#{tag_class.table_name}.name = '" +
834
- with_all_tags.join(
835
- "\' OR #{tag_class.table_name}.name=\'") + "'"
836
- with_all_tags_sql = <<-SQL
837
- SELECT #{item_class.table_name}.*
838
- FROM #{options[:join_table]}, #{item_class.table_name},
839
- #{tag_class.table_name}
840
- WHERE #{options[:join_table]}.#{tag_foreign_key} =
841
- #{tag_class.table_name}.#{tag_class.primary_key}
842
- AND (#{tag_name_condition})
843
- AND #{item_class.table_name}.#{item_class.primary_key} =
844
- #{options[:join_table]}.#{item_foreign_key}
845
- GROUP BY #{group_by_string}
846
- HAVING COUNT(
847
- #{item_class.table_name}.#{item_class.primary_key}) =
848
- #{with_all_tags.size}
849
- SQL
850
- with_all_tags_results =
851
- item_class.find_by_sql(with_all_tags_sql)
852
- end
889
+ tag_name_condition = "#{tag_class.table_name}.name = '" +
890
+ with_all_tags.join(
891
+ "\' OR #{tag_class.table_name}.name=\'") + "'"
892
+ with_all_tags_sql = <<-SQL
893
+ SELECT #{item_class.table_name}.*
894
+ FROM #{options[:join_table]}, #{item_class.table_name},
895
+ #{tag_class.table_name}
896
+ WHERE #{options[:join_table]}.#{tag_foreign_key} =
897
+ #{tag_class.table_name}.#{tag_class.primary_key}
898
+ AND (#{tag_name_condition})
899
+ AND #{item_class.table_name}.#{item_class.primary_key} =
900
+ #{options[:join_table]}.#{item_foreign_key}
901
+ GROUP BY #{group_by_string}
902
+ HAVING COUNT(
903
+ #{item_class.table_name}.#{item_class.primary_key}) =
904
+ #{with_all_tags.size}
905
+ SQL
906
+ with_all_tags_results =
907
+ item_class.find_by_sql(with_all_tags_sql)
853
908
  end
854
909
 
855
910
  with_any_tags_results = nil
856
911
  if with_any_tags != nil && with_any_tags.size > 0
857
- with_any_tags_query_thread = Thread.new do
858
- with_any_tags_sql = <<-SQL
859
- SELECT #{item_class.table_name}.*
860
- FROM #{options[:join_table]}, #{item_class.table_name},
861
- #{tag_class.table_name}
862
- WHERE #{tag_class.table_name}.name
863
- IN ('#{with_any_tags.join('\', \'')}')
864
- AND #{tag_class.table_name}.#{tag_class.primary_key} =
865
- #{options[:join_table]}.#{tag_foreign_key}
866
- AND #{item_class.table_name}.#{item_class.primary_key} =
867
- #{options[:join_table]}.#{item_foreign_key}
868
- GROUP BY #{group_by_string}
869
- SQL
870
- with_any_tags_results =
871
- item_class.find_by_sql(with_any_tags_sql)
872
- end
912
+ with_any_tags_sql = <<-SQL
913
+ SELECT #{item_class.table_name}.*
914
+ FROM #{options[:join_table]}, #{item_class.table_name},
915
+ #{tag_class.table_name}
916
+ WHERE #{tag_class.table_name}.name
917
+ IN ('#{with_any_tags.join('\', \'')}')
918
+ AND #{tag_class.table_name}.#{tag_class.primary_key} =
919
+ #{options[:join_table]}.#{tag_foreign_key}
920
+ AND #{item_class.table_name}.#{item_class.primary_key} =
921
+ #{options[:join_table]}.#{item_foreign_key}
922
+ GROUP BY #{group_by_string}
923
+ SQL
924
+ with_any_tags_results =
925
+ item_class.find_by_sql(with_any_tags_sql)
873
926
  end
874
927
 
875
- if with_all_tags != nil && with_all_tags.size > 0
876
- with_all_tags_query_thread.join
877
- end
878
- if with_any_tags != nil && with_any_tags.size > 0
879
- with_any_tags_query_thread.join
880
- end
881
928
  if with_any_tags_results != nil &&
882
929
  with_any_tags_results.size > 0 &&
883
930
  with_all_tags_results != nil &&
@@ -987,6 +1034,214 @@ module ActiveRecord #:nodoc:
987
1034
  end
988
1035
  end
989
1036
 
1037
+ # This module allows you to add additional generic functionality to your
1038
+ # Tag class by simply extending the TaggingHelpers module.
1039
+ #
1040
+ # Example:
1041
+ # class Tag < ActiveRecord::Base
1042
+ # extend TaggingHelpers
1043
+ # end
1044
+ module TaggingHelpers
1045
+ # Unlike the tag_query class method on tagged classes, this will search
1046
+ # across the entire tagged space, returning any tagged object, regardless
1047
+ # of type, that matches the query criteria.
1048
+ #
1049
+ # Options are:
1050
+ # * <tt>:with_all_tags</tt> - An array of strings, returns all tagged
1051
+ # objects that have all of the tags specified within the array.
1052
+ # * <tt>:with_any_tags</tt> - An array of strings, returns all tagged
1053
+ # objects that have any of the tags specified within the array.
1054
+ # * <tt>:without_tags</tt> - An array of strings, removes all tagged
1055
+ # objects that have any of the tags specified within the array from
1056
+ # the list of results that would have otherwise been returned.
1057
+ # Throws an error if used in the absence of of either of the other
1058
+ # two options.
1059
+ # * <tt>:user_id</tt> - An integer id for the user that this query
1060
+ # is specific to. Only tags that this user has created will be
1061
+ # taken into account with this query. Globally scoped tag associations
1062
+ # will be not be included in the results if this option is set.
1063
+ def tag_query(options = {})
1064
+ if self.class != Class
1065
+ raise "You must extend your tag class with the TaggingHelpers module."
1066
+ end
1067
+ unless options.kind_of? Hash
1068
+ raise "The options parameter must be a hash."
1069
+ end
1070
+ validate_options([:with_any_tags, :with_all_tags,
1071
+ :without_tags, :user_id], options.keys)
1072
+ if options.size == 0
1073
+ raise "You must supply either the with_any_tags option, " +
1074
+ "the with_all_tags option, or both."
1075
+ end
1076
+ with_any_tags = options[:with_any_tags]
1077
+ unless with_any_tags.nil?
1078
+ with_any_tags.collect! { |tag| tag.to_s }
1079
+ with_any_tags.uniq!
1080
+ end
1081
+ with_all_tags = options[:with_all_tags]
1082
+ unless with_all_tags.nil?
1083
+ with_all_tags.collect! { |tag| tag.to_s }
1084
+ with_all_tags.uniq!
1085
+ end
1086
+ without_tags = options[:without_tags]
1087
+ unless without_tags.nil?
1088
+ without_tags.collect! { |tag| tag.to_s }
1089
+ without_tags.uniq!
1090
+ end
1091
+ if without_tags != nil && with_any_tags == nil &&
1092
+ with_all_tags == nil
1093
+ raise(ActiveRecord::ActiveRecordError,
1094
+ "Cannot run this query, nothing to search for.")
1095
+ end
1096
+ tagging_user_id = options[:user_id]
1097
+ results = []
1098
+
1099
+ for association_hash in self.instance_variable_get("@tagged_classes")
1100
+
1101
+ # Load variables from the association_hash
1102
+ tag_class = association_hash[:tag_class]
1103
+ tag_foreign_key = association_hash[:tag_foreign_key]
1104
+ item_class = association_hash[:item_class]
1105
+ item_foreign_key = association_hash[:item_foreign_key]
1106
+ user_class = association_hash[:user_class]
1107
+ user_foreign_key = association_hash[:user_foreign_key]
1108
+ join_table = association_hash[:join_table]
1109
+
1110
+ # If they specified a user_id, and this association is a globally
1111
+ # scoped tag association, skip to the next association.
1112
+ if tagging_user_id != nil && user_class.nil?
1113
+ next
1114
+ end
1115
+
1116
+ group_by_string = item_class.table_name + "." +
1117
+ item_class.column_names.join(
1118
+ ", #{item_class.table_name}.")
1119
+ tagging_user_id_string = ""
1120
+ unless tagging_user_id.nil?
1121
+ tagging_user_id_string =
1122
+ "AND #{join_table}.#{user_foreign_key} = #{tagging_user_id}"
1123
+ end
1124
+
1125
+ with_all_tags_results = nil
1126
+ if with_all_tags != nil && with_all_tags.size > 0
1127
+ tag_name_condition = "#{tag_class.table_name}.name = '" +
1128
+ with_all_tags.join(
1129
+ "\' OR #{tag_class.table_name}.name=\'") + "'"
1130
+ with_all_tags_sql = <<-SQL
1131
+ SELECT #{item_class.table_name}.*
1132
+ FROM #{join_table}, #{item_class.table_name},
1133
+ #{tag_class.table_name}
1134
+ WHERE #{join_table}.#{tag_foreign_key} =
1135
+ #{tag_class.table_name}.#{tag_class.primary_key}
1136
+ AND (#{tag_name_condition})
1137
+ AND #{item_class.table_name}.#{item_class.primary_key} =
1138
+ #{join_table}.#{item_foreign_key}
1139
+ #{tagging_user_id_string}
1140
+ GROUP BY #{group_by_string}
1141
+ HAVING COUNT(
1142
+ #{item_class.table_name}.#{item_class.primary_key}) >=
1143
+ #{with_all_tags.size}
1144
+ SQL
1145
+ with_all_tags_results =
1146
+ item_class.find_by_sql(with_all_tags_sql)
1147
+ if tagging_user_id.nil?
1148
+ for result in with_all_tags_results
1149
+ result_tags = result.tags.map do |tag|
1150
+ tag.name
1151
+ end
1152
+ if (result_tags & with_all_tags).size != with_all_tags.size
1153
+ # Reject result
1154
+ with_all_tags_results.delete(result)
1155
+ end
1156
+ end
1157
+ end
1158
+ end
1159
+
1160
+ with_any_tags_results = nil
1161
+ if with_any_tags != nil && with_any_tags.size > 0
1162
+ with_any_tags_sql = <<-SQL
1163
+ SELECT #{item_class.table_name}.*
1164
+ FROM #{join_table}, #{item_class.table_name},
1165
+ #{tag_class.table_name}
1166
+ WHERE #{tag_class.table_name}.name
1167
+ IN ('#{with_any_tags.join('\', \'')}')
1168
+ AND #{tag_class.table_name}.#{tag_class.primary_key} =
1169
+ #{join_table}.#{tag_foreign_key}
1170
+ AND #{item_class.table_name}.#{item_class.primary_key} =
1171
+ #{join_table}.#{item_foreign_key}
1172
+ #{tagging_user_id_string}
1173
+ GROUP BY #{group_by_string}
1174
+ SQL
1175
+ with_any_tags_results =
1176
+ item_class.find_by_sql(with_any_tags_sql)
1177
+ end
1178
+
1179
+ if with_any_tags_results != nil &&
1180
+ with_any_tags_results.size > 0 &&
1181
+ with_all_tags_results != nil &&
1182
+ with_all_tags_results.size > 0
1183
+ results.concat(with_all_tags_results & with_any_tags_results)
1184
+ elsif with_any_tags_results != nil &&
1185
+ with_any_tags_results.size > 0
1186
+ results.concat(with_any_tags_results)
1187
+ elsif with_all_tags_results != nil &&
1188
+ with_all_tags_results.size > 0
1189
+ results.concat(with_all_tags_results)
1190
+ end
1191
+ end
1192
+
1193
+ if without_tags != nil && without_tags.size > 0
1194
+ for result in results
1195
+ if tagging_user_id.nil?
1196
+ if ((result.tags.map { |tag| tag.name }) &
1197
+ without_tags).size > 0
1198
+ results.delete(result)
1199
+ end
1200
+ else
1201
+ if ((result.user_tags(tagging_user_id).map { |tag| tag.name }) &
1202
+ without_tags).size > 0
1203
+ results.delete(result)
1204
+ end
1205
+ end
1206
+ end
1207
+ end
1208
+ return results
1209
+ end
1210
+
1211
+ # Takes a string and converts it to a tag object, creating the tag object
1212
+ # if it doesn't yet exist.
1213
+ def create_tag(raw_tag)
1214
+ if self.class != Class
1215
+ raise "You must extend your tag class with the TaggingHelpers module."
1216
+ end
1217
+ return nil if raw_tag.nil?
1218
+ if raw_tag.kind_of? self
1219
+ return raw_tag
1220
+ end
1221
+ tag_object = self.find_by_name(raw_tag.to_s)
1222
+ if tag_object.nil?
1223
+ tag_object = self.new
1224
+ tag_object.name = raw_tag.to_s
1225
+ tag_object.save
1226
+ end
1227
+ return tag_object
1228
+ end
1229
+
1230
+ # Takes a string and converts it to a tag object, returning nil if it
1231
+ # doesn't yet exist.
1232
+ def get_tag(raw_tag)
1233
+ if self.class != Class
1234
+ raise "You must extend your tag class with the TaggingHelpers module."
1235
+ end
1236
+ return nil if raw_tag.nil?
1237
+ if raw_tag.kind_of? self
1238
+ return raw_tag
1239
+ end
1240
+ tag_object = self.find_by_name(raw_tag.to_s)
1241
+ return tag_object
1242
+ end
1243
+ end
1244
+
990
1245
  ActiveRecord::Base.class_eval do
991
1246
  include ActiveRecord::Acts::Taggable
992
1247
  end
data/rakefile CHANGED
@@ -7,7 +7,7 @@ require 'rake/gempackagetask'
7
7
  require 'rake/contrib/rubyforgepublisher'
8
8
 
9
9
  PKG_NAME = 'tagtools'
10
- PKG_VERSION = '0.0.2'
10
+ PKG_VERSION = '0.0.3'
11
11
  PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
12
12
 
13
13
  RELEASE_NAME = "REL #{PKG_VERSION}"
@@ -31,6 +31,7 @@ rescue
31
31
  end
32
32
 
33
33
  class Tag < ActiveRecord::Base
34
+ extend TaggingHelpers
34
35
  end
35
36
 
36
37
  class Image < ActiveRecord::Base
@@ -44,6 +45,12 @@ class GlobalTagsTest < Test::Unit::TestCase
44
45
  ActiveRecord::Base.connection.execute("DELETE FROM tags")
45
46
  end
46
47
 
48
+ def teardown
49
+ ActiveRecord::Base.connection.execute("DELETE FROM images_tags")
50
+ ActiveRecord::Base.connection.execute("DELETE FROM images")
51
+ ActiveRecord::Base.connection.execute("DELETE FROM tags")
52
+ end
53
+
47
54
  def test_add_tags_existing_record
48
55
  ruby_on_rails = Image.new
49
56
  ruby_on_rails.url = "http://www.rubyonrails.com/logo.gif"
@@ -142,4 +149,39 @@ class GlobalTagsTest < Test::Unit::TestCase
142
149
  assert_equal(2,
143
150
  ruby_on_rails.tags(true).size)
144
151
  end
152
+
153
+ def test_tag_helpers
154
+ ruby_on_rails = Image.new
155
+ ruby_on_rails.url = "http://www.rubyonrails.com/logo.gif"
156
+ ruby_on_rails.save
157
+ ruby_on_rails.tags << "ruby"
158
+ ruby_on_rails.tags << "rails"
159
+ ruby_on_rails.tags << "framework"
160
+ red_handed = Image.new
161
+ red_handed.url = "http://redhanded.hobix.com/logo.gif"
162
+ red_handed.save
163
+ red_handed.tags << "ruby"
164
+ red_handed.tags << "cult"
165
+
166
+ tag = Tag.get_tag("ruby")
167
+ assert_equal("ruby", tag.name)
168
+ tag = Tag.get_tag("non-existant")
169
+ assert_equal(nil, tag)
170
+ tag = Tag.create_tag("ruby")
171
+ assert_equal("ruby", tag.name)
172
+ tag = Tag.create_tag("non-existant")
173
+ assert_equal("non-existant", tag.name)
174
+
175
+ results = Tag.tag_query(:with_all_tags => ["ruby", "cult"])
176
+ assert_equal(red_handed, results.first)
177
+ results = Tag.tag_query(:with_all_tags => ["ruby", "framework"])
178
+ assert_equal(ruby_on_rails, results.first)
179
+ results = Tag.tag_query(:with_any_tags => ["cult", "framework"])
180
+ assert(results.include?(ruby_on_rails))
181
+ assert(results.include?(red_handed))
182
+ results = Tag.tag_query(:with_all_tags => ["ruby", "framework"],
183
+ :without_tags => ["cult"])
184
+ assert_equal(ruby_on_rails, results.first)
185
+ assert(!results.include?(red_handed))
186
+ end
145
187
  end
@@ -34,6 +34,7 @@ class User < ActiveRecord::Base
34
34
  end
35
35
 
36
36
  class Tag < ActiveRecord::Base
37
+ extend TaggingHelpers
37
38
  end
38
39
 
39
40
  class Bookmark < ActiveRecord::Base
@@ -48,6 +49,13 @@ class UserTagsTest < Test::Unit::TestCase
48
49
  ActiveRecord::Base.connection.execute("DELETE FROM users")
49
50
  ActiveRecord::Base.connection.execute("DELETE FROM tags")
50
51
  end
52
+
53
+ def teardown
54
+ ActiveRecord::Base.connection.execute("DELETE FROM bookmarks_tags_users")
55
+ ActiveRecord::Base.connection.execute("DELETE FROM bookmarks")
56
+ ActiveRecord::Base.connection.execute("DELETE FROM users")
57
+ ActiveRecord::Base.connection.execute("DELETE FROM tags")
58
+ end
51
59
 
52
60
  def test_add_tags_existing_record
53
61
  some_guy = User.new
@@ -90,6 +98,9 @@ class UserTagsTest < Test::Unit::TestCase
90
98
  some_guy = User.new
91
99
  some_guy.name = "Joe Normal"
92
100
  some_guy.save
101
+ some_other_guy = User.new
102
+ some_other_guy.name = "Joe Abnormal"
103
+ some_other_guy.save
93
104
  ruby_on_rails = Bookmark.new
94
105
  ruby_on_rails.url = "http://www.rubyonrails.com"
95
106
  ruby_on_rails.save
@@ -101,17 +112,40 @@ class UserTagsTest < Test::Unit::TestCase
101
112
  red_handed.save
102
113
  red_handed.user_tags(some_guy.id) << "ruby"
103
114
  red_handed.user_tags(some_guy.id) << "cult"
115
+ red_handed.user_tags(some_other_guy.id) << "spinach"
116
+ red_handed.user_tags(some_other_guy.id) << "turkey"
117
+ red_handed.user_tags(some_other_guy.id) << "atlantis"
118
+ red_handed.user_tags(some_other_guy.id) << "ruby"
119
+
104
120
  results = Bookmark.tag_query(:with_all_tags => ["ruby", "cult"])
105
121
  assert_equal(red_handed, results.first)
122
+ assert_equal(1, results.size)
106
123
  results = Bookmark.tag_query(:with_all_tags => ["ruby", "framework"])
107
124
  assert_equal(ruby_on_rails, results.first)
125
+ assert_equal(1, results.size)
108
126
  results = Bookmark.tag_query(:with_any_tags => ["cult", "framework"])
109
127
  assert(results.include?(ruby_on_rails))
110
128
  assert(results.include?(red_handed))
129
+ assert_equal(2, results.size)
111
130
  results = Bookmark.tag_query(:with_all_tags => ["ruby", "framework"],
112
131
  :without_tags => ["cult"])
113
132
  assert_equal(ruby_on_rails, results.first)
114
133
  assert(!results.include?(red_handed))
134
+ assert_equal(1, results.size)
135
+ results = Bookmark.tag_query(:with_all_tags => ["ruby", "framework"],
136
+ :without_tags => ["cult"], :user_id => some_guy.id)
137
+ assert_equal(ruby_on_rails, results.first)
138
+ assert(!results.include?(red_handed))
139
+ assert_equal(1, results.size)
140
+ results = Bookmark.tag_query(:with_all_tags => ["spinach"],
141
+ :with_any_tags => ["ruby", "cult", "rails", "framework"],
142
+ :without_tags => ["cult"], :user_id => some_other_guy.id)
143
+ assert_equal(red_handed, results.first)
144
+ assert(!results.include?(ruby_on_rails))
145
+ assert_equal(1, results.size)
146
+ results = Bookmark.tag_query(:with_all_tags => ["ruby", "framework"],
147
+ :without_tags => ["cult"], :user_id => -1)
148
+ assert_equal(0, results.size)
115
149
  end
116
150
 
117
151
  def test_include
@@ -161,4 +195,69 @@ class UserTagsTest < Test::Unit::TestCase
161
195
  assert_equal(2,
162
196
  ruby_on_rails.user_tags(some_guy.id, true).size)
163
197
  end
198
+
199
+ def test_tag_helpers
200
+ some_guy = User.new
201
+ some_guy.name = "Joe Normal"
202
+ some_guy.save
203
+ some_other_guy = User.new
204
+ some_other_guy.name = "Joe Abnormal"
205
+ some_other_guy.save
206
+ ruby_on_rails = Bookmark.new
207
+ ruby_on_rails.url = "http://www.rubyonrails.com"
208
+ ruby_on_rails.save
209
+ ruby_on_rails.user_tags(some_guy.id) << "ruby"
210
+ ruby_on_rails.user_tags(some_guy.id) << "rails"
211
+ ruby_on_rails.user_tags(some_guy.id) << "framework"
212
+ red_handed = Bookmark.new
213
+ red_handed.url = "http://redhanded.hobix.com"
214
+ red_handed.save
215
+ red_handed.user_tags(some_guy.id) << "ruby"
216
+ red_handed.user_tags(some_guy.id) << "cult"
217
+ red_handed.user_tags(some_other_guy.id) << "spinach"
218
+ red_handed.user_tags(some_other_guy.id) << "turkey"
219
+ red_handed.user_tags(some_other_guy.id) << "atlantis"
220
+ red_handed.user_tags(some_other_guy.id) << "ruby"
221
+
222
+ tag = Tag.get_tag("ruby")
223
+ assert_equal("ruby", tag.name)
224
+ tag = Tag.get_tag("non-existant")
225
+ assert_equal(nil, tag)
226
+ tag = Tag.create_tag("ruby")
227
+ assert_equal("ruby", tag.name)
228
+ tag = Tag.create_tag("non-existant")
229
+ assert_equal("non-existant", tag.name)
230
+
231
+ results = Tag.tag_query(:with_all_tags => ["ruby", "cult"])
232
+ assert_equal(red_handed, results.first)
233
+ assert_equal(1, results.size)
234
+ $foo = true
235
+ results = Tag.tag_query(:with_all_tags => ["ruby", "framework"])
236
+ $foo = false
237
+ assert_equal(ruby_on_rails, results.first)
238
+ assert_equal(1, results.size)
239
+ results = Tag.tag_query(:with_any_tags => ["cult", "framework"])
240
+ assert(results.include?(ruby_on_rails))
241
+ assert(results.include?(red_handed))
242
+ assert_equal(2, results.size)
243
+ results = Tag.tag_query(:with_all_tags => ["ruby", "framework"],
244
+ :without_tags => ["cult"])
245
+ assert_equal(ruby_on_rails, results.first)
246
+ assert(!results.include?(red_handed))
247
+ assert_equal(1, results.size)
248
+ results = Tag.tag_query(:with_all_tags => ["ruby", "framework"],
249
+ :without_tags => ["cult"], :user_id => some_guy.id)
250
+ assert_equal(ruby_on_rails, results.first)
251
+ assert(!results.include?(red_handed))
252
+ assert_equal(1, results.size)
253
+ results = Tag.tag_query(:with_all_tags => ["spinach"],
254
+ :with_any_tags => ["ruby", "cult", "rails", "framework"],
255
+ :without_tags => ["cult"], :user_id => some_other_guy.id)
256
+ assert_equal(red_handed, results.first)
257
+ assert(!results.include?(ruby_on_rails))
258
+ assert_equal(1, results.size)
259
+ results = Tag.tag_query(:with_all_tags => ["ruby", "framework"],
260
+ :without_tags => ["cult"], :user_id => -1)
261
+ assert_equal(0, results.size)
262
+ end
164
263
  end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: tagtools
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.0.2
7
- date: 2005-09-09 00:00:00 -04:00
6
+ version: 0.0.3
7
+ date: 2005-09-21 00:00:00 -04:00
8
8
  summary: Folksonomy system for Rails.
9
9
  require_paths:
10
10
  - lib