summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorshadoi <shadoi@980ebf18-57e1-0310-9a29-db15c13687c0>2006-12-14 23:35:50 +0000
committershadoi <shadoi@980ebf18-57e1-0310-9a29-db15c13687c0>2006-12-14 23:35:50 +0000
commitb5fd82260d5cd05e594c6adf87f1c1017ecf07fe (patch)
treebd4e6405323a396eb7220bafb87354dcabb679cb /lib
parent98ebb870d4da4efb0abcec52405c52bfff528cf0 (diff)
downloadpuppet-b5fd82260d5cd05e594c6adf87f1c1017ecf07fe.tar.gz
puppet-b5fd82260d5cd05e594c6adf87f1c1017ecf07fe.tar.xz
puppet-b5fd82260d5cd05e594c6adf87f1c1017ecf07fe.zip
acts_as_taggable plugin
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@1927 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'lib')
-rw-r--r--lib/puppet/rails/lib/README4
-rw-r--r--lib/puppet/rails/lib/acts_as_taggable.rb58
-rw-r--r--lib/puppet/rails/lib/init.rb5
-rw-r--r--lib/puppet/rails/lib/tag.rb40
-rw-r--r--lib/puppet/rails/lib/tagging.rb12
5 files changed, 119 insertions, 0 deletions
diff --git a/lib/puppet/rails/lib/README b/lib/puppet/rails/lib/README
new file mode 100644
index 000000000..8d2f90822
--- /dev/null
+++ b/lib/puppet/rails/lib/README
@@ -0,0 +1,4 @@
+Acts As Taggable
+=================
+
+Allows for tags to be added to multiple classes. \ No newline at end of file
diff --git a/lib/puppet/rails/lib/acts_as_taggable.rb b/lib/puppet/rails/lib/acts_as_taggable.rb
new file mode 100644
index 000000000..e9bd03696
--- /dev/null
+++ b/lib/puppet/rails/lib/acts_as_taggable.rb
@@ -0,0 +1,58 @@
+module ActiveRecord
+ module Acts #:nodoc:
+ module Taggable #:nodoc:
+ def self.included(base)
+ base.extend(ClassMethods)
+ end
+
+ module ClassMethods
+ def acts_as_taggable(options = {})
+ write_inheritable_attribute(:acts_as_taggable_options, {
+ :taggable_type => ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s,
+ :from => options[:from]
+ })
+
+ class_inheritable_reader :acts_as_taggable_options
+
+ has_many :taggings, :as => :taggable, :dependent => true
+ has_many :tags, :through => :taggings
+
+ include ActiveRecord::Acts::Taggable::InstanceMethods
+ extend ActiveRecord::Acts::Taggable::SingletonMethods
+ end
+ end
+
+ module SingletonMethods
+ def find_tagged_with(list)
+ find_by_sql([
+ "SELECT #{table_name}.* FROM #{table_name}, tags, taggings " +
+ "WHERE #{table_name}.#{primary_key} = taggings.taggable_id " +
+ "AND taggings.taggable_type = ? " +
+ "AND taggings.tag_id = tags.id AND tags.name IN (?)",
+ acts_as_taggable_options[:taggable_type], list
+ ])
+ end
+ end
+
+ module InstanceMethods
+ def tag_with(list)
+ Tag.transaction do
+ taggings.destroy_all
+
+ Tag.parse(list).each do |name|
+ if acts_as_taggable_options[:from]
+ send(acts_as_taggable_options[:from]).tags.find_or_create_by_name(name).on(self)
+ else
+ Tag.find_or_create_by_name(name).on(self)
+ end
+ end
+ end
+ end
+
+ def tag_list
+ tags.collect { |tag| tag.name.include?(" ") ? "'#{tag.name}'" : tag.name }.join(" ")
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/lib/puppet/rails/lib/init.rb b/lib/puppet/rails/lib/init.rb
new file mode 100644
index 000000000..0a07e5c8e
--- /dev/null
+++ b/lib/puppet/rails/lib/init.rb
@@ -0,0 +1,5 @@
+require 'puppet/rails/lib/acts_as_taggable'
+ActiveRecord::Base.send(:include, ActiveRecord::Acts::Taggable)
+
+require 'puppet/rails/lib/tagging'
+require 'puppet/rails/lib/tag'
diff --git a/lib/puppet/rails/lib/tag.rb b/lib/puppet/rails/lib/tag.rb
new file mode 100644
index 000000000..ca31171b2
--- /dev/null
+++ b/lib/puppet/rails/lib/tag.rb
@@ -0,0 +1,40 @@
+class Tag < ActiveRecord::Base
+ has_many :taggings
+
+ def self.parse(list)
+ tag_names = []
+
+ # first, pull out the quoted tags
+ list.gsub!(/\"(.*?)\"\s*/ ) { tag_names << $1; "" }
+
+ # then, replace all commas with a space
+ list.gsub!(/,/, " ")
+
+ # then, get whatever's left
+ tag_names.concat list.split(/\s/)
+
+ # strip whitespace from the names
+ tag_names = tag_names.map { |t| t.strip }
+
+ # delete any blank tag names
+ tag_names = tag_names.delete_if { |t| t.empty? }
+
+ return tag_names
+ end
+
+ def tagged
+ @tagged ||= taggings.collect { |tagging| tagging.taggable }
+ end
+
+ def on(taggable)
+ taggings.create :taggable => taggable
+ end
+
+ def ==(comparison_object)
+ super || name == comparison_object.to_s
+ end
+
+ def to_s
+ name
+ end
+end \ No newline at end of file
diff --git a/lib/puppet/rails/lib/tagging.rb b/lib/puppet/rails/lib/tagging.rb
new file mode 100644
index 000000000..e06e88a14
--- /dev/null
+++ b/lib/puppet/rails/lib/tagging.rb
@@ -0,0 +1,12 @@
+class Tagging < ActiveRecord::Base
+ belongs_to :tag
+ belongs_to :taggable, :polymorphic => true
+
+ def self.tagged_class(taggable)
+ ActiveRecord::Base.send(:class_name_of_active_record_descendant, taggable.class).to_s
+ end
+
+ def self.find_taggable(tagged_class, tagged_id)
+ tagged_class.constantize.find(tagged_id)
+ end
+end \ No newline at end of file