tagtools 0.0.2 → 0.0.3

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