radiant-tags-extension 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/HELP.md +50 -0
- data/HELP_admin.md +30 -0
- data/README +38 -0
- data/Rakefile +25 -0
- data/app/models/meta_tag.rb +53 -0
- data/app/models/radius_tags.rb +328 -0
- data/app/models/tag_search_page.rb +87 -0
- data/app/models/tagging.rb +10 -0
- data/app/views/admin/help/_using_tags.html.haml +4 -0
- data/app/views/admin/pages/_tag_field.html.haml +8 -0
- data/db/migrate/001_add_tag_support.rb +20 -0
- data/lib/tagging_methods.rb +128 -0
- data/lib/tasks/tags_extension_tasks.rake +32 -0
- data/public/stylesheets/tags.css +11 -0
- data/tags_extension.rb +57 -0
- data/test/fixtures/meta_tags.yml +12 -0
- data/test/fixtures/page_parts.yml +17 -0
- data/test/fixtures/pages.yml +43 -0
- data/test/fixtures/taggings.yml +20 -0
- data/test/functional/tag_search_page_test.rb +44 -0
- data/test/functional/tags_extension_test.rb +19 -0
- data/test/helpers/render_test_helper.rb +60 -0
- data/test/test_helper.rb +20 -0
- data/test/unit/page_taggability_test.rb +20 -0
- data/vendor/plugins/has_many_polymorphs/.gitignore +1 -0
- data/vendor/plugins/has_many_polymorphs/CHANGELOG +86 -0
- data/vendor/plugins/has_many_polymorphs/LICENSE +184 -0
- data/vendor/plugins/has_many_polymorphs/Manifest +173 -0
- data/vendor/plugins/has_many_polymorphs/README +205 -0
- data/vendor/plugins/has_many_polymorphs/Rakefile +28 -0
- data/vendor/plugins/has_many_polymorphs/TODO +2 -0
- data/vendor/plugins/has_many_polymorphs/examples/hmph.rb +69 -0
- data/vendor/plugins/has_many_polymorphs/generators/tagging/tagging_generator.rb +97 -0
- data/vendor/plugins/has_many_polymorphs/generators/tagging/templates/migration.rb +28 -0
- data/vendor/plugins/has_many_polymorphs/generators/tagging/templates/tag.rb +39 -0
- data/vendor/plugins/has_many_polymorphs/generators/tagging/templates/tag_test.rb +15 -0
- data/vendor/plugins/has_many_polymorphs/generators/tagging/templates/tagging.rb +16 -0
- data/vendor/plugins/has_many_polymorphs/generators/tagging/templates/tagging_extensions.rb +203 -0
- data/vendor/plugins/has_many_polymorphs/generators/tagging/templates/tagging_test.rb +85 -0
- data/vendor/plugins/has_many_polymorphs/generators/tagging/templates/taggings.yml +23 -0
- data/vendor/plugins/has_many_polymorphs/generators/tagging/templates/tags.yml +7 -0
- data/vendor/plugins/has_many_polymorphs/init.rb +2 -0
- data/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/association.rb +160 -0
- data/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/autoload.rb +69 -0
- data/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/base.rb +60 -0
- data/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/class_methods.rb +600 -0
- data/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/configuration.rb +19 -0
- data/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/debugging_tools.rb +103 -0
- data/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/rake_task_redefine_task.rb +35 -0
- data/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/reflection.rb +58 -0
- data/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs/support_methods.rb +88 -0
- data/vendor/plugins/has_many_polymorphs/lib/has_many_polymorphs.rb +27 -0
- data/vendor/plugins/has_many_polymorphs/test/fixtures/bow_wows.yml +10 -0
- data/vendor/plugins/has_many_polymorphs/test/fixtures/cats.yml +18 -0
- data/vendor/plugins/has_many_polymorphs/test/fixtures/eaters_foodstuffs.yml +0 -0
- data/vendor/plugins/has_many_polymorphs/test/fixtures/fish.yml +12 -0
- data/vendor/plugins/has_many_polymorphs/test/fixtures/frogs.yml +5 -0
- data/vendor/plugins/has_many_polymorphs/test/fixtures/keep_your_enemies_close.yml +0 -0
- data/vendor/plugins/has_many_polymorphs/test/fixtures/little_whale_pupils.yml +0 -0
- data/vendor/plugins/has_many_polymorphs/test/fixtures/people.yml +7 -0
- data/vendor/plugins/has_many_polymorphs/test/fixtures/petfoods.yml +11 -0
- data/vendor/plugins/has_many_polymorphs/test/fixtures/whales.yml +5 -0
- data/vendor/plugins/has_many_polymorphs/test/fixtures/wild_boars.yml +10 -0
- data/vendor/plugins/has_many_polymorphs/test/generator/tagging_generator_test.rb +42 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/README +182 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/Rakefile +19 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/controllers/application.rb +7 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/controllers/bones_controller.rb +5 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/helpers/addresses_helper.rb +2 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/helpers/application_helper.rb +3 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/helpers/bones_helper.rb +2 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/helpers/sellers_helper.rb +28 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/helpers/states_helper.rb +2 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/helpers/users_helper.rb +2 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/models/bone.rb +2 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/models/double_sti_parent.rb +2 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/models/double_sti_parent_relationship.rb +2 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/models/organic_substance.rb +2 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/models/single_sti_parent.rb +4 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/models/single_sti_parent_relationship.rb +4 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/models/stick.rb +2 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/models/stone.rb +2 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/addresses/edit.html.erb +12 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/addresses/index.html.erb +18 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/addresses/new.html.erb +11 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/addresses/show.html.erb +3 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/bones/index.rhtml +5 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/layouts/addresses.html.erb +17 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/layouts/sellers.html.erb +17 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/layouts/states.html.erb +17 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/layouts/users.html.erb +17 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/sellers/edit.html.erb +12 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/sellers/index.html.erb +20 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/sellers/new.html.erb +11 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/sellers/show.html.erb +3 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/states/edit.html.erb +12 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/states/index.html.erb +19 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/states/new.html.erb +11 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/states/show.html.erb +3 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/users/edit.html.erb +12 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/users/index.html.erb +22 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/users/new.html.erb +11 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/app/views/users/show.html.erb +3 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/config/boot.rb +110 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/config/database.yml +17 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/config/environment.rb +19 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/config/environment.rb.canonical +19 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/config/environments/development.rb +9 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/config/environments/production.rb +18 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/config/environments/test.rb +19 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/config/locomotive.yml +6 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/config/routes.rb +33 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/config/ultrasphinx/default.base +56 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/config/ultrasphinx/development.conf.canonical +155 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/001_create_sticks.rb +11 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/002_create_stones.rb +11 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/003_create_organic_substances.rb +11 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/004_create_bones.rb +8 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/005_create_single_sti_parents.rb +11 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/006_create_double_sti_parents.rb +11 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/007_create_single_sti_parent_relationships.rb +13 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/008_create_double_sti_parent_relationships.rb +14 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/db/migrate/009_create_library_model.rb +11 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/doc/README_FOR_APP +2 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/generators/commenting_generator_test.rb +83 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/lib/library_model.rb +2 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/public/.htaccess +40 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/public/404.html +30 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/public/500.html +30 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/public/dispatch.cgi +10 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/public/dispatch.fcgi +24 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/public/dispatch.rb +10 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/public/favicon.ico +0 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/public/images/rails.png +0 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/public/index.html +277 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/public/javascripts/application.js +2 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/public/javascripts/controls.js +833 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/public/javascripts/dragdrop.js +942 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/public/javascripts/effects.js +1088 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/public/javascripts/prototype.js +2515 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/public/robots.txt +1 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/public/stylesheets/scaffold.css +74 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/script/about +3 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/script/breakpointer +3 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/script/console +3 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/script/destroy +3 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/script/generate +3 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/script/performance/benchmarker +3 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/script/performance/profiler +3 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/script/plugin +3 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/script/process/inspector +3 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/script/process/reaper +3 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/script/process/spawner +3 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/script/runner +3 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/script/server +3 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/double_sti_parent_relationships.yml +7 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/double_sti_parents.yml +7 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/organic_substances.yml +5 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/single_sti_parent_relationships.yml +7 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/single_sti_parents.yml +7 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/sticks.yml +7 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/fixtures/stones.yml +7 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/addresses_controller_test.rb +57 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/bones_controller_test.rb +8 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/sellers_controller_test.rb +57 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/states_controller_test.rb +57 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/functional/users_controller_test.rb +57 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/test_helper.rb +8 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/bone_test.rb +8 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/double_sti_parent_relationship_test.rb +8 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/double_sti_parent_test.rb +8 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/organic_substance_test.rb +8 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/single_sti_parent_relationship_test.rb +8 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/single_sti_parent_test.rb +8 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/stick_test.rb +8 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/app/test/unit/stone_test.rb +8 -0
- data/vendor/plugins/has_many_polymorphs/test/integration/server_test.rb +43 -0
- data/vendor/plugins/has_many_polymorphs/test/models/aquatic/fish.rb +5 -0
- data/vendor/plugins/has_many_polymorphs/test/models/aquatic/pupils_whale.rb +7 -0
- data/vendor/plugins/has_many_polymorphs/test/models/aquatic/whale.rb +15 -0
- data/vendor/plugins/has_many_polymorphs/test/models/beautiful_fight_relationship.rb +26 -0
- data/vendor/plugins/has_many_polymorphs/test/models/canine.rb +9 -0
- data/vendor/plugins/has_many_polymorphs/test/models/cat.rb +5 -0
- data/vendor/plugins/has_many_polymorphs/test/models/dog.rb +18 -0
- data/vendor/plugins/has_many_polymorphs/test/models/eaters_foodstuff.rb +8 -0
- data/vendor/plugins/has_many_polymorphs/test/models/frog.rb +4 -0
- data/vendor/plugins/has_many_polymorphs/test/models/kitten.rb +3 -0
- data/vendor/plugins/has_many_polymorphs/test/models/parentship.rb +4 -0
- data/vendor/plugins/has_many_polymorphs/test/models/person.rb +9 -0
- data/vendor/plugins/has_many_polymorphs/test/models/petfood.rb +39 -0
- data/vendor/plugins/has_many_polymorphs/test/models/tabby.rb +2 -0
- data/vendor/plugins/has_many_polymorphs/test/models/wild_boar.rb +3 -0
- data/vendor/plugins/has_many_polymorphs/test/modules/extension_module.rb +9 -0
- data/vendor/plugins/has_many_polymorphs/test/modules/other_extension_module.rb +9 -0
- data/vendor/plugins/has_many_polymorphs/test/patches/symlinked_plugins_1.2.6.diff +46 -0
- data/vendor/plugins/has_many_polymorphs/test/schema.rb +87 -0
- data/vendor/plugins/has_many_polymorphs/test/setup.rb +14 -0
- data/vendor/plugins/has_many_polymorphs/test/test_helper.rb +52 -0
- data/vendor/plugins/has_many_polymorphs/test/unit/has_many_polymorphs_test.rb +713 -0
- metadata +421 -0
@@ -0,0 +1,128 @@
|
|
1
|
+
TaggingMethods = Proc.new do
|
2
|
+
|
3
|
+
def valid_with_tags?
|
4
|
+
return (self.errors.empty? && valid_without_tags?)
|
5
|
+
end
|
6
|
+
alias_method_chain :valid?, :tags
|
7
|
+
|
8
|
+
def tag_with tags
|
9
|
+
self.save if self.new_record?
|
10
|
+
# just skip the whole method if the tags string hasn't changed
|
11
|
+
return if tags == tag_list
|
12
|
+
# do we need to delete any tags?
|
13
|
+
tags_to_delete = tag_list.split(MetaTag::DELIMITER) - tags.split(MetaTag::DELIMITER)
|
14
|
+
tags_to_delete.select{|t| meta_tags.delete(MetaTag.find_by_name(t))}
|
15
|
+
|
16
|
+
tags.split(MetaTag::DELIMITER).each do |tag|
|
17
|
+
begin
|
18
|
+
tag = MetaTag.find_or_initialize_by_name(tag.strip.squeeze(" "))
|
19
|
+
meta_tags << tag unless meta_tags.include?(tag)
|
20
|
+
rescue ActiveRecord::RecordInvalid => e
|
21
|
+
errors.add_to_base("Tags can not contain special characters")
|
22
|
+
rescue ActiveRecord::StatementInvalid => e
|
23
|
+
# With SQLite3 - a duplicate tagging will result in the following message:
|
24
|
+
# SQLite3::SQLException: SQL logic error or missing database: INSERT INTO taggings ("meta_tag_id", "taggable_type", "taggable_id") VALUES(11, 'Page', 74)
|
25
|
+
# raise unless e.to_s =~ /duplicate/i
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
alias :meta_tags= :tag_with
|
31
|
+
|
32
|
+
def tag_list
|
33
|
+
meta_tags.map(&:name).join(MetaTag::DELIMITER)
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Find all the objects tagged with the supplied list of tags
|
38
|
+
#
|
39
|
+
# Usage : Model.tagged_with("ruby")
|
40
|
+
# Model.tagged_with("hello", "world")
|
41
|
+
# Model.tagged_with("hello", "world", :limit => 10)
|
42
|
+
#
|
43
|
+
def self.tagged_with(*tag_list)
|
44
|
+
options = tag_list.extract_options!
|
45
|
+
tag_list = parse_tags(tag_list)
|
46
|
+
|
47
|
+
scope = scope(:find)
|
48
|
+
options[:select] ||= "#{table_name}.*"
|
49
|
+
options[:from] ||= "#{table_name}, meta_tags, taggings"
|
50
|
+
|
51
|
+
sql = "SELECT #{(scope && scope[:select]) || options[:select]} "
|
52
|
+
sql << "FROM #{(scope && scope[:from]) || options[:from]} "
|
53
|
+
|
54
|
+
add_joins!(sql, options[:joins], scope)
|
55
|
+
|
56
|
+
sql << "WHERE #{table_name}.#{primary_key} = taggings.taggable_id "
|
57
|
+
sql << "AND taggings.taggable_type = '#{ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s}' "
|
58
|
+
sql << "AND taggings.meta_tag_id = meta_tags.id "
|
59
|
+
sql << "AND pages.site_id = #{current_site.id} " if self.respond_to?(:current_site)
|
60
|
+
|
61
|
+
tag_list_condition = tag_list.map {|name| "\"#{name.strip.squeeze(' ')}\""}.join(", ")
|
62
|
+
|
63
|
+
sql << "AND (meta_tags.name IN (#{sanitize_sql(tag_list_condition)})) "
|
64
|
+
sql << "AND #{sanitize_sql(options[:conditions])} " if options[:conditions]
|
65
|
+
|
66
|
+
columns = column_names.map do |column|
|
67
|
+
"#{table_name}.#{column}"
|
68
|
+
end.join(", ")
|
69
|
+
|
70
|
+
sql << "GROUP BY #{columns} "
|
71
|
+
sql << "HAVING COUNT(taggings.meta_tag_id) = #{tag_list.size}"
|
72
|
+
|
73
|
+
add_order!(sql, options[:order], scope)
|
74
|
+
add_limit!(sql, options, scope)
|
75
|
+
add_lock!(sql, options, scope)
|
76
|
+
|
77
|
+
|
78
|
+
find_by_sql(sql)
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.tagged_with_any(*tag_list)
|
82
|
+
options = tag_list.extract_options!
|
83
|
+
tag_list = parse_tags(tag_list)
|
84
|
+
|
85
|
+
scope = scope(:find)
|
86
|
+
options[:select] ||= "#{table_name}.*"
|
87
|
+
options[:from] ||= "#{table_name}, meta_tags, taggings"
|
88
|
+
|
89
|
+
sql = "SELECT #{(scope && scope[:select]) || options[:select]} "
|
90
|
+
sql << "FROM #{(scope && scope[:from]) || options[:from]} "
|
91
|
+
|
92
|
+
add_joins!(sql, options[:joins], scope)
|
93
|
+
|
94
|
+
sql << "WHERE #{table_name}.#{primary_key} = taggings.taggable_id "
|
95
|
+
sql << "AND taggings.taggable_type = '#{ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s}' "
|
96
|
+
sql << "AND taggings.meta_tag_id = meta_tags.id "
|
97
|
+
sql << "AND pages.site_id = #{current_site.id} " if self.respond_to?(:current_site)
|
98
|
+
|
99
|
+
sql << "AND ("
|
100
|
+
sql << tag_list.inject([]) do |arr,name|
|
101
|
+
arr << sanitize_sql(["meta_tags.name = ?", name.strip.squeeze(' ')])
|
102
|
+
end.join(" OR ")
|
103
|
+
sql << ") "
|
104
|
+
|
105
|
+
|
106
|
+
sql << "AND #{sanitize_sql(options[:conditions])} " if options[:conditions]
|
107
|
+
|
108
|
+
columns = column_names.map do |column|
|
109
|
+
"#{table_name}.#{column}"
|
110
|
+
end.join(", ")
|
111
|
+
|
112
|
+
sql << "GROUP BY #{columns} "
|
113
|
+
|
114
|
+
add_order!(sql, options[:order], scope)
|
115
|
+
add_limit!(sql, options, scope)
|
116
|
+
add_lock!(sql, options, scope)
|
117
|
+
|
118
|
+
find_by_sql(sql)
|
119
|
+
end
|
120
|
+
|
121
|
+
def self.parse_tags(tags)
|
122
|
+
return [] if tags.blank?
|
123
|
+
tags = Array(tags).first
|
124
|
+
tags = tags.respond_to?(:flatten) ? tags.flatten : tags.split(MetaTag::DELIMITER)
|
125
|
+
tags.map { |tag| tag.strip.squeeze(" ") }.flatten.compact.uniq
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
namespace :radiant do
|
2
|
+
namespace :extensions do
|
3
|
+
namespace :tags do
|
4
|
+
|
5
|
+
desc "Runs the migration and update tasks of the Tags extension"
|
6
|
+
task :install => [:environment, :migrate, :update]
|
7
|
+
|
8
|
+
desc "Runs the migration of the Tags extension"
|
9
|
+
task :migrate => :environment do
|
10
|
+
require 'radiant/extension_migrator'
|
11
|
+
if ENV["VERSION"]
|
12
|
+
TagsExtension.migrator.migrate(ENV["VERSION"].to_i)
|
13
|
+
else
|
14
|
+
TagsExtension.migrator.migrate
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "Copy needed files to public dir"
|
19
|
+
task :update => :environment do
|
20
|
+
is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
|
21
|
+
Dir[TagsExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
|
22
|
+
path = file.sub(TagsExtension.root, '')
|
23
|
+
directory = File.dirname(path)
|
24
|
+
puts "Copying #{path}..."
|
25
|
+
mkdir_p RAILS_ROOT + directory
|
26
|
+
cp file, RAILS_ROOT + path
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
ol.tag_cloud { list-style: none; }
|
2
|
+
.tag_cloud li { display: inline; }
|
3
|
+
/* hide the extra context from CSS-enabled browsers, but not screenreaders */
|
4
|
+
.tag_cloud span { position: absolute; left: 0px; top: -500px; width: 1px; height: 1px; overflow: hidden; }
|
5
|
+
|
6
|
+
.tag_cloud .size1 { font-size: 1em; }
|
7
|
+
.tag_cloud .size2 { font-size: 1.3em; }
|
8
|
+
.tag_cloud .size3 { font-size: 1.6em; }
|
9
|
+
.tag_cloud .size4 { font-size: 1.9em; }
|
10
|
+
.tag_cloud .size5 { font-size: 2.2em; }
|
11
|
+
.tag_cloud .size6 { font-size: 2.5em; }
|
data/tags_extension.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require_dependency 'application_controller'
|
2
|
+
require File.dirname(__FILE__)+'/lib/tagging_methods'
|
3
|
+
require 'radiant-tags-extension'
|
4
|
+
|
5
|
+
class TagsExtension < Radiant::Extension
|
6
|
+
version RadiantTagsExtension::VERSION
|
7
|
+
description "This extension enhances the page model with tagging capabilities, tagging as in \"2.0\" and tagclouds."
|
8
|
+
url "http://gorilla-webdesign.be"
|
9
|
+
|
10
|
+
DEFAULT_RESULTS_URL = '/search/by-tag'
|
11
|
+
|
12
|
+
define_routes do |map|
|
13
|
+
if Radiant::Config['tags.results_page_url'].blank?
|
14
|
+
Radiant::Config['tags.results_page_url'] = TagsExtension::DEFAULT_RESULTS_URL if Radiant::Config['tags.results_page_url'].blank?
|
15
|
+
end
|
16
|
+
begin
|
17
|
+
if defined?(SiteLanguage) && SiteLanguage.count > 0
|
18
|
+
include Globalize
|
19
|
+
SiteLanguage.codes.each do |code|
|
20
|
+
langname = Locale.new(code).language.code
|
21
|
+
map.connect "#{langname}#{Radiant::Config['tags.results_page_url']}/:tag", :controller => 'site', :action => 'show_page', :url => Radiant::Config['tags.results_page_url'], :language => code
|
22
|
+
end
|
23
|
+
else if defined?(VhostExtension)
|
24
|
+
map.connect "#{Radiant::Config['tags.results_page_url']}/:tag", :controller => 'site', :action => 'show_page', :url => Radiant::Config['tags.results_page_url']
|
25
|
+
end
|
26
|
+
map.connect "#{Radiant::Config['tags.results_page_url']}/:tag", :controller => 'site', :action => 'show_page', :url => Radiant::Config['tags.results_page_url']
|
27
|
+
end
|
28
|
+
rescue
|
29
|
+
# dirty hack; need to get trough here to allow migrations to run..
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def activate
|
34
|
+
raise "The Shards extension is required and must be loaded first!" unless defined?(admin.page)
|
35
|
+
if Radiant::Config.table_exists?
|
36
|
+
Radiant::Config['tags.results_page_url'] = TagsExtension::DEFAULT_RESULTS_URL unless Radiant::Config['tags.results_page_url']
|
37
|
+
Radiant::Config['tags.complex_strings'] = 'false' unless Radiant::Config['tags.complex_strings']
|
38
|
+
end
|
39
|
+
TagSearchPage
|
40
|
+
Page.send :include, RadiusTags
|
41
|
+
begin
|
42
|
+
MetaTag
|
43
|
+
rescue
|
44
|
+
# dirty hack; need to get trough here to allow migrations to run..
|
45
|
+
end
|
46
|
+
Page.module_eval &TaggingMethods
|
47
|
+
admin.page.edit.add :extended_metadata, 'tag_field'
|
48
|
+
|
49
|
+
# HELP
|
50
|
+
if admin.respond_to?(:help)
|
51
|
+
admin.help.index.add :page_details, 'using_tags', :after => 'breadcrumbs'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def deactivate
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
display_tags_part:
|
2
|
+
id: 1
|
3
|
+
page_id: 5
|
4
|
+
name: body
|
5
|
+
content:
|
6
|
+
<h1>Results for <r:search:query /></h1>
|
7
|
+
<r:search:empty>
|
8
|
+
<h2>No pages tagged with "<r:search:query/>".</h2>
|
9
|
+
</r:search:empty>
|
10
|
+
<r:search:results>
|
11
|
+
<h2>These pages are tagged with "<r:search:query/>".</h2>
|
12
|
+
<ul>
|
13
|
+
<r:search:results:each order="desc" by="published_at">
|
14
|
+
<li><r:link/> door <r:author/> op <r:date/></li>
|
15
|
+
</r:search:results:each>
|
16
|
+
</ul>
|
17
|
+
</r:search:results>
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
|
2
|
+
homepage:
|
3
|
+
id: 1
|
4
|
+
title: Ruby Home Page
|
5
|
+
breadcrumb: Home
|
6
|
+
slug: /
|
7
|
+
status_id: 100
|
8
|
+
parent_id:
|
9
|
+
published_at: 2006-01-30 08:41:07
|
10
|
+
documentation:
|
11
|
+
id: 2
|
12
|
+
title: Documentation
|
13
|
+
breadcrumb: Documentation
|
14
|
+
slug: documentation
|
15
|
+
status_id: 100
|
16
|
+
parent_id: 1
|
17
|
+
published_at: 2006-01-31 08:41:07
|
18
|
+
books:
|
19
|
+
id: 3
|
20
|
+
title: Books
|
21
|
+
breadcrumb: Books
|
22
|
+
slug: books
|
23
|
+
status_id: 100
|
24
|
+
parent_id: 2
|
25
|
+
published_at: 2006-01-30 08:41:07
|
26
|
+
textile:
|
27
|
+
id: 4
|
28
|
+
title: Textile
|
29
|
+
breadcrumb: Textile
|
30
|
+
slug: textile
|
31
|
+
status_id: 100
|
32
|
+
parent_id: 1
|
33
|
+
published_at: 2006-01-30 08:41:07
|
34
|
+
|
35
|
+
tags_page:
|
36
|
+
id: 5
|
37
|
+
title: Tags Page
|
38
|
+
breadcrumb: tags
|
39
|
+
slug: tags
|
40
|
+
status_id: 100
|
41
|
+
parent_id: 1
|
42
|
+
class_name: TagSearchPage
|
43
|
+
published_at: 2006-01-30 08:41:07
|
@@ -0,0 +1,20 @@
|
|
1
|
+
1:
|
2
|
+
meta_tag_id: 1
|
3
|
+
taggable_id: 1
|
4
|
+
taggable_type: Page
|
5
|
+
2:
|
6
|
+
meta_tag_id: 2
|
7
|
+
taggable_id: 1
|
8
|
+
taggable_type: Page
|
9
|
+
3:
|
10
|
+
meta_tag_id: 3
|
11
|
+
taggable_id: 1
|
12
|
+
taggable_type: Page
|
13
|
+
4:
|
14
|
+
meta_tag_id: 1
|
15
|
+
taggable_id: 2
|
16
|
+
taggable_type: Page
|
17
|
+
5:
|
18
|
+
meta_tag_id: 2
|
19
|
+
taggable_id: 2
|
20
|
+
taggable_type: Page
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class TagSearchPageTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
fixtures :pages, :meta_tags, :taggings, :page_parts
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@page = pages(:tags_page)
|
9
|
+
@page.request = ActionController::TestRequest.new
|
10
|
+
@page.response = ActionController::TestResponse.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_title_gets_set_ok
|
14
|
+
@page.request.request_parameters = {:tag => "foo"}
|
15
|
+
@page.render
|
16
|
+
assert_equal "Tagged with foo", @page.title
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_no_title_means_no_title_change
|
20
|
+
@page.render
|
21
|
+
assert_equal "Tags Page", @page.title
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_page_should_show_posts_tagged_with_tag
|
25
|
+
@page.request.request_parameters = {:tag => "lorem"}
|
26
|
+
output = @page.render
|
27
|
+
assert_match /These pages are tagged with "lorem"/, output
|
28
|
+
assert_match /Ruby Home Page/, output
|
29
|
+
assert_match /Documentation/, output
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_resulting_pages_should_be_sorted
|
33
|
+
@page.request.request_parameters = {:tag => "lorem"}
|
34
|
+
output = @page.render
|
35
|
+
assert_match /Documentation.*Ruby Home Page/, output
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_unknown_tag_should_say_so
|
39
|
+
@page.request.request_parameters = {:tag => "foobarbar"}
|
40
|
+
output = @page.render
|
41
|
+
assert_match /No pages tagged with "foobarbar"/, output
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class TagsExtensionTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
fixtures :pages, :meta_tags, :taggings
|
6
|
+
test_helper :render
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@page = pages(:documentation)
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_cloud_tag
|
13
|
+
assert_renders "<ol class=\"tag_cloud\"><li class=\"size2\"><span>1 page is tagged with </span><a href=\"?q=dolor\" class=\"tag\">dolor</a></li><li class=\"size3\"><span>2 pages are tagged with </span><a href=\"?q=ipsum\" class=\"tag\">ipsum</a></li><li class=\"size3\"><span>2 pages are tagged with </span><a href=\"?q=lorem\" class=\"tag\">lorem</a></li></ol>", "<r:tag_cloud />"
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_tag_list
|
17
|
+
assert_renders "<a href=\"?q=ipsum\" class=\"tag\">ipsum</a>, <a href=\"?q=lorem\" class=\"tag\">lorem</a>", "<r:tag_list />"
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module RenderTestHelper
|
2
|
+
|
3
|
+
def assert_renders(expected, input, url = nil, host = nil)
|
4
|
+
output = get_render_output(input, url, host)
|
5
|
+
message = "<#{expected.inspect}> expected but was <#{output.inspect}>"
|
6
|
+
assert_block(message) { expected == output }
|
7
|
+
end
|
8
|
+
|
9
|
+
def assert_render_match(regexp, input, url = nil)
|
10
|
+
regexp = Regexp.new(regexp) if regexp.kind_of? String
|
11
|
+
output = get_render_output(input, url)
|
12
|
+
message = "<#{output.inspect}> expected to be =~ <#{regexp.inspect}>"
|
13
|
+
assert_block(message) { output =~ regexp }
|
14
|
+
end
|
15
|
+
|
16
|
+
def assert_render_error(expected_error_message, input, url = nil)
|
17
|
+
output = get_render_output(input, url)
|
18
|
+
message = "expected error message <#{expected_error_message.inspect}> expected but none was thrown"
|
19
|
+
assert_block(message) { false }
|
20
|
+
rescue => e
|
21
|
+
message = "expected error message <#{expected_error_message.inspect}> but was <#{e.message.inspect}>"
|
22
|
+
assert_block(message) { expected_error_message === e.message }
|
23
|
+
end
|
24
|
+
|
25
|
+
def assert_headers(expected_headers, url = nil)
|
26
|
+
setup_page(url)
|
27
|
+
headers = @page.headers
|
28
|
+
message = "<#{expected_headers.inspect}> expected but was <#{headers.inspect}>"
|
29
|
+
assert_block(message) { expected_headers == headers }
|
30
|
+
end
|
31
|
+
|
32
|
+
def assert_page_renders(page_name, expected, message = nil)
|
33
|
+
page = pages(page_name)
|
34
|
+
output = page.render
|
35
|
+
message = "<#{expected.inspect}> expected, but was <#{output.inspect}>"
|
36
|
+
assert_block(message) { expected == output }
|
37
|
+
end
|
38
|
+
|
39
|
+
def assert_snippet_renders(snippet_name, expected, message = nil)
|
40
|
+
snippet = snippets(snippet_name)
|
41
|
+
output = @page.render_snippet(snippet)
|
42
|
+
message = "<#{expected.inspect}> expected, but was <#{output.inspect}>"
|
43
|
+
assert_block(message) { expected == output }
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def get_render_output(input, url, host = nil)
|
49
|
+
setup_page(url, host)
|
50
|
+
@page.send(:parse, input)
|
51
|
+
end
|
52
|
+
|
53
|
+
def setup_page(url = nil, host = nil)
|
54
|
+
@page.request = ActionController::TestRequest.new
|
55
|
+
@page.request.request_uri = (url || @page.url)
|
56
|
+
@page.request.host = host || "testhost.tld"
|
57
|
+
@page.response = ActionController::TestResponse.new
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
# Load the the environment
|
3
|
+
unless defined? RADIANT_ROOT
|
4
|
+
ENV["RAILS_ENV"] = "test"
|
5
|
+
require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../")}/config/environment"
|
6
|
+
end
|
7
|
+
require "#{RADIANT_ROOT}/test/test_helper"
|
8
|
+
|
9
|
+
class Test::Unit::TestCase
|
10
|
+
|
11
|
+
# Include a helper to make testing Radius tags easier
|
12
|
+
test_helper :render
|
13
|
+
|
14
|
+
# Add the fixture directory to the fixture path
|
15
|
+
self.fixture_path << File.dirname(__FILE__) + "/fixtures"
|
16
|
+
|
17
|
+
fixtures :users, :pages
|
18
|
+
# Add more helper methods to be used by all extension tests here...
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class PageTaggabilityTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@page = Page.find 1
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_page_should_be_taggable
|
9
|
+
assert true, @page.respond_to?("tag_with")
|
10
|
+
assert_difference MetaTag, :count, 2 do
|
11
|
+
@page.tag_with 'lorem ipsum'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def assert_difference(object, method = nil, difference = 1)
|
16
|
+
initial_value = object.send(method)
|
17
|
+
yield
|
18
|
+
assert_equal initial_value + difference, object.send(method), "#{object}##{method}"
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
test/integration/app/log
|
@@ -0,0 +1,86 @@
|
|
1
|
+
v2.2. Various fixes.
|
2
|
+
|
3
|
+
v2.13. Merge various fixes for Rails 2.2.2.
|
4
|
+
|
5
|
+
v2.12. Improvements to the test suite; bugfixes for STI children (rsl). Remove fancy dependency system in favor of using Dispatcher::to_prepare every time.
|
6
|
+
|
7
|
+
v2.11. Rails 1.2.6 tagging generator compatibility; change test suite to use included integration app.
|
8
|
+
|
9
|
+
v2.10. Add :parent_conditions option; bugfix for nullified conditions; bugfix for self-referential tagging generator; allow setting of has_many_polymorphs_options hash in Configuration's after_initialize if you need to adjust the autoload behavior; clear error message on missing or improperly namespaced models; fix .build on double-sided relationships; add :namespace key for easier set up of Camping apps or other unusual class structures.
|
10
|
+
|
11
|
+
v2.9. Gem version renumbering; my apologies if this messes anyone up.
|
12
|
+
|
13
|
+
v2.8. RDoc documentation; repository relocation; Rakefile cleanup; remove deprecated plugin-specific class caching.
|
14
|
+
|
15
|
+
v2.7.5. Various bugfixes; Postgres problems may remain on edge.
|
16
|
+
|
17
|
+
v2.7.3. Use new :source and :source_type options in 1.2.3 (David Lemstra); fix pluralization bug; add some tests; experimental tagging generator.
|
18
|
+
|
19
|
+
v2.7.2. Deprecate has_many_polymorphs_cache_classes= option because it doesn't really work. Use config.cache_classes= instead to cache all reloadable items.
|
20
|
+
|
21
|
+
v2.7.1. Dispatcher.to_prepare didn't fire in the console; now using a config.after_initialize wrapper instead.
|
22
|
+
|
23
|
+
v2.7. Dependency injection framework elimates having to care about load order.
|
24
|
+
|
25
|
+
v2.6. Make the logger act sane for the gem version.
|
26
|
+
|
27
|
+
v2.5.2. Allow :skip_duplicates on double relationships.
|
28
|
+
|
29
|
+
v2.5.1. Renamed :ignore_duplicates to :skip_duplicates to better express its non-passive behavior; made sure not to load target set on push unless necessary.
|
30
|
+
|
31
|
+
v2.5. Activerecord compatibility branch becomes trunk: extra options now supported for double polymorphism; conditions nulled-out and propogated to child relationships; more tests; new :ignore_duplicates option on macro can be set to false if you want << to push duplicate associations.
|
32
|
+
|
33
|
+
v2.4.1. Code split into multiple files; tests added for pluralization check; Rails 1.1.6 no longer supported.
|
34
|
+
|
35
|
+
v2.4. Unlimited mixed class association extensions for both single and double targets and joins.
|
36
|
+
|
37
|
+
v2.3. Gem version
|
38
|
+
|
39
|
+
v2.2. API change; prefix on methods is now singular when using :rename_individual_collections.
|
40
|
+
|
41
|
+
v2.1. Add configuration option to cache polymorphic classes in development mode.
|
42
|
+
|
43
|
+
v2.0. Collection methods (push, delete, clear) now on individual collections.
|
44
|
+
|
45
|
+
v1.9.2. Disjoint collection sides bugfix, don't raise on new records.
|
46
|
+
|
47
|
+
v1.9.1. Double classify bugfix.
|
48
|
+
|
49
|
+
v1.9. Large changes to properly support double polymorphism.
|
50
|
+
|
51
|
+
v1.8.2. Bugfix to make sure the type gets checked on doubly polymorphic parents.
|
52
|
+
|
53
|
+
v1.8.1. Bugfix for sqlite3 child attribute retrieval.
|
54
|
+
|
55
|
+
v1.8. Bugfix for instantiating attributes of namespaced models.
|
56
|
+
|
57
|
+
v1.7.1. Bugfix for double polymorphic relationships.
|
58
|
+
|
59
|
+
v1.7. Double polymorphic relationships (includes new API method).
|
60
|
+
|
61
|
+
v1.6. Namespaced model support.
|
62
|
+
|
63
|
+
v1.5. Bugfix for Postgres and Mysql under 1.1.6; refactored tests (hildofur); properly handles legacy table names set with set_table_name().
|
64
|
+
|
65
|
+
v1.4. STI support added (use the child class names, not the base class).
|
66
|
+
|
67
|
+
v1.3. Bug regarding table names with underscores in SQL query fixed.
|
68
|
+
|
69
|
+
v1.2. License change, again.
|
70
|
+
|
71
|
+
v1.1. File_column bug fixed.
|
72
|
+
|
73
|
+
v1.0. Tests written; after_find and after_initialize now correctly called.
|
74
|
+
|
75
|
+
v0.5. SQL performance enhancements added.
|
76
|
+
|
77
|
+
v0.4. Rewrote singletons as full-fledged proxy class so that marshalling works (e.g. in the session).
|
78
|
+
|
79
|
+
v0.3. Caching added.
|
80
|
+
|
81
|
+
v0.2. Fixed dependency reloading problem in development mode.
|
82
|
+
|
83
|
+
v0.1. License change.
|
84
|
+
|
85
|
+
v0. Added :dependent support on the join table; no changelog before this version.
|
86
|
+
|