mirror of
https://github.com/TracksApp/tracks.git
synced 2025-12-31 22:38:49 +01:00
Removed superfluous 'tracks' directory at the root of the repository.
Testing commits to github.
This commit is contained in:
parent
6a42901514
commit
4cbf5a34d3
2269 changed files with 0 additions and 0 deletions
94
vendor/plugins/has_many_polymorphs/generators/commenting/commenting_generator.rb
vendored
Normal file
94
vendor/plugins/has_many_polymorphs/generators/commenting/commenting_generator.rb
vendored
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
|
||||
class CommentingGenerator < Rails::Generator::NamedBase
|
||||
default_options :skip_migration => false
|
||||
default_options :self_referential => false
|
||||
attr_reader :parent_association_name
|
||||
attr_reader :commentable_models
|
||||
|
||||
def initialize(runtime_args, runtime_options = {})
|
||||
@parent_association_name = (runtime_args.include?("--self-referential") ? "commenter" : "comment")
|
||||
@commentable_models = runtime_args.reject{|opt| opt =~ /^--/}.map do |commentable|
|
||||
":" + commentable.underscore.pluralize
|
||||
end
|
||||
@commentable_models += [":comments"] if runtime_args.include?("--self-referential")
|
||||
@commentable_models.uniq!
|
||||
|
||||
verify @commentable_models
|
||||
hacks
|
||||
runtime_args.unshift("placeholder")
|
||||
super
|
||||
end
|
||||
|
||||
def verify models
|
||||
puts "** Warning: only one commentable model specified; tests may not run properly." if models.size < 2
|
||||
models.each do |model|
|
||||
model = model[1..-1].classify
|
||||
next if model == "Comment" # don't load ourselves when --self-referential is used
|
||||
self.class.const_get(model) rescue puts "** Error: model #{model[1..-1].classify} could not be loaded." or exit
|
||||
end
|
||||
end
|
||||
|
||||
def hacks
|
||||
# add the extension require in environment.rb
|
||||
phrase = "require 'commenting_extensions'"
|
||||
filename = "#{RAILS_ROOT}/config/environment.rb"
|
||||
unless (open(filename) do |file|
|
||||
file.grep(/#{Regexp.escape phrase}/).any?
|
||||
end)
|
||||
open(filename, 'a+') do |file|
|
||||
file.puts "\n" + phrase + "\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def manifest
|
||||
record do |m|
|
||||
m.class_collisions class_path, class_name, "#{class_name}Test"
|
||||
|
||||
m.directory File.join('app/models', class_path)
|
||||
m.directory File.join('test/unit', class_path)
|
||||
m.directory File.join('test/fixtures', class_path)
|
||||
m.directory File.join('test/fixtures', class_path)
|
||||
m.directory File.join('lib')
|
||||
|
||||
m.template 'comment.rb', File.join('app/models', class_path, "comment.rb")
|
||||
m.template 'comment_test.rb', File.join('test/unit', class_path, "comment_test.rb")
|
||||
m.template 'comments.yml', File.join('test/fixtures', class_path, "comments.yml")
|
||||
|
||||
m.template 'commenting.rb', File.join('app/models', class_path, "commenting.rb")
|
||||
m.template 'commenting_test.rb', File.join('test/unit', class_path, "commenting_test.rb")
|
||||
m.template 'commentings.yml', File.join('test/fixtures', class_path, "commentings.yml")
|
||||
|
||||
m.template 'commenting_extensions.rb', File.join('lib', 'commenting_extensions.rb')
|
||||
|
||||
unless options[:skip_migration]
|
||||
m.migration_template 'migration.rb', 'db/migrate',
|
||||
:migration_file_name => "create_comments_and_commentings"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
def banner
|
||||
"Usage: #{$0} generate commenting [CommentableModelA CommentableModelB ...]"
|
||||
end
|
||||
|
||||
def add_options!(opt)
|
||||
opt.separator ''
|
||||
opt.separator 'Options:'
|
||||
opt.on("--skip-migration",
|
||||
"Don't generate a migration file for this model") { |v| options[:skip_migration] = v }
|
||||
opt.on("--self-referential",
|
||||
"Allow comments to comment themselves.") { |v| options[:self_referential] = v }
|
||||
end
|
||||
|
||||
# Useful for generating tests/fixtures
|
||||
def model_one
|
||||
commentable_models[0][1..-1].classify
|
||||
end
|
||||
|
||||
def model_two
|
||||
commentable_models[1][1..-1].classify rescue model_one
|
||||
end
|
||||
end
|
||||
33
vendor/plugins/has_many_polymorphs/generators/commenting/templates/comment.rb
vendored
Normal file
33
vendor/plugins/has_many_polymorphs/generators/commenting/templates/comment.rb
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
# The Comment model. This model is automatically generated and added to your app if you run the commenting generator.
|
||||
|
||||
class Comment < ActiveRecord::Base
|
||||
|
||||
# If database speed becomes an issue, you could remove these validations and rescue the ActiveRecord database constraint errors instead.
|
||||
validates_presence_of :name, :email, :body
|
||||
validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
|
||||
|
||||
after_validation :prepend_url
|
||||
|
||||
# Set up the polymorphic relationship.
|
||||
has_many_polymorphs :commentables,
|
||||
:from => [<%= commentable_models.join(", ") %>],
|
||||
:through => :commentings,
|
||||
:dependent => :destroy,
|
||||
<% if options[:self_referential] -%> :as => :<%= parent_association_name -%>,
|
||||
<% end -%>
|
||||
:parent_extend => proc {
|
||||
}
|
||||
|
||||
# Tag::Error class. Raised by ActiveRecord::Base::TaggingExtensions if something goes wrong.
|
||||
class Error < StandardError
|
||||
end
|
||||
|
||||
protected
|
||||
def prepend_url
|
||||
return if self[:url].blank?
|
||||
if self[:url] !~ /^http(s):\/\//i
|
||||
self.url = 'http://' + self[:url]
|
||||
end
|
||||
end
|
||||
end
|
||||
12
vendor/plugins/has_many_polymorphs/generators/commenting/templates/comment_test.rb
vendored
Normal file
12
vendor/plugins/has_many_polymorphs/generators/commenting/templates/comment_test.rb
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class CommentTest < Test::Unit::TestCase
|
||||
fixtures :comments, :commentings, <%= commentable_models[0..1].join(", ") -%>
|
||||
|
||||
def test_to_s
|
||||
assert_equal "no1@nowhere.com", <%= model_two -%>.find(2).comments.first.email
|
||||
assert_equal "http://letrails.cn", <%= model_two -%>.find(2).comments.last.url
|
||||
assert_equal "http://fr.ivolo.us", <%= model_two -%>.find(2).comments.first.url
|
||||
end
|
||||
|
||||
end
|
||||
13
vendor/plugins/has_many_polymorphs/generators/commenting/templates/commenting.rb
vendored
Normal file
13
vendor/plugins/has_many_polymorphs/generators/commenting/templates/commenting.rb
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
# The Commenting join model. This model is automatically generated and added to your app if you run the commenting generator.
|
||||
|
||||
class Commenting < ActiveRecord::Base
|
||||
|
||||
belongs_to :<%= parent_association_name -%><%= ", :foreign_key => \"#{parent_association_name}_id\", :class_name => \"Comment\"" if options[:self_referential] %>
|
||||
belongs_to :commentable, :polymorphic => true
|
||||
|
||||
# This callback makes sure that an orphaned <tt>Comment</tt> is deleted if it no longer tags anything.
|
||||
def before_destroy
|
||||
<%= parent_association_name -%>.destroy_without_callbacks if <%= parent_association_name -%> and <%= parent_association_name -%>.commentings.count == 1
|
||||
end
|
||||
end
|
||||
30
vendor/plugins/has_many_polymorphs/generators/commenting/templates/commenting_extensions.rb
vendored
Normal file
30
vendor/plugins/has_many_polymorphs/generators/commenting/templates/commenting_extensions.rb
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
class ActiveRecord::Base
|
||||
module CommentingExtensions
|
||||
|
||||
def comment_count
|
||||
commentable?
|
||||
self.comments.size
|
||||
end
|
||||
|
||||
def comment_with(attributes)
|
||||
commentable?(true)
|
||||
begin
|
||||
comment = Comment.create(attributes)
|
||||
raise Comment::Error, "Comment could not be saved with" if comment.new_record?
|
||||
comment.commentables << self
|
||||
rescue
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def commentable?(should_raise = false) #:nodoc:
|
||||
unless flag = respond_to?(:<%= parent_association_name -%>s)
|
||||
raise "#{self.class} is not a commentable model" if should_raise
|
||||
end
|
||||
flag
|
||||
end
|
||||
end
|
||||
|
||||
include CommentingExtensions
|
||||
end
|
||||
|
||||
30
vendor/plugins/has_many_polymorphs/generators/commenting/templates/commenting_test.rb
vendored
Normal file
30
vendor/plugins/has_many_polymorphs/generators/commenting/templates/commenting_test.rb
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class CommentingTest < Test::Unit::TestCase
|
||||
fixtures :commentings, :comments, <%= commentable_models[0..1].join(", ") -%>
|
||||
|
||||
def setup
|
||||
@obj1 = <%= model_two %>.find(1)
|
||||
@obj2 = <%= model_two %>.find(2)
|
||||
<% if commentable_models.size > 1 -%>
|
||||
@obj3 = <%= model_one -%>.find(1)
|
||||
<% end -%>
|
||||
@comment1 = Comment.find(1)
|
||||
@comment2 = Comment.find(2)
|
||||
@commenting1 = Commenting.find(1)
|
||||
end
|
||||
|
||||
def test_commentable
|
||||
assert_raises(RuntimeError) do
|
||||
@commenting1.send(:commentable?, true)
|
||||
end
|
||||
assert !@commenting1.send(:commentable?)
|
||||
<% if commentable_models.size > 1 -%>
|
||||
assert @obj3.send(:commentable?)
|
||||
<% end -%>
|
||||
<% if options[:self_referential] -%>
|
||||
assert @comment1.send(:commentable?)
|
||||
<% end -%>
|
||||
end
|
||||
|
||||
end
|
||||
23
vendor/plugins/has_many_polymorphs/generators/commenting/templates/commentings.yml
vendored
Normal file
23
vendor/plugins/has_many_polymorphs/generators/commenting/templates/commentings.yml
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
<% if commentable_models.size > 1 -%>
|
||||
commentings_003:
|
||||
<%= parent_association_name -%>_id: "2"
|
||||
id: "3"
|
||||
commentable_type: <%= model_one %>
|
||||
commentable_id: "1"
|
||||
<% end -%>
|
||||
commentings_004:
|
||||
<%= parent_association_name -%>_id: "2"
|
||||
id: "4"
|
||||
commentable_type: <%= model_two %>
|
||||
commentable_id: "2"
|
||||
commentings_001:
|
||||
<%= parent_association_name -%>_id: "1"
|
||||
id: "1"
|
||||
commentable_type: <%= model_two %>
|
||||
commentable_id: "1"
|
||||
commentings_002:
|
||||
<%= parent_association_name -%>_id: "1"
|
||||
id: "2"
|
||||
commentable_type: <%= model_two %>
|
||||
commentable_id: "2"
|
||||
13
vendor/plugins/has_many_polymorphs/generators/commenting/templates/comments.yml
vendored
Normal file
13
vendor/plugins/has_many_polymorphs/generators/commenting/templates/comments.yml
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
comments_001:
|
||||
id: "1"
|
||||
name: frivolous
|
||||
email: no1@nowhere.com
|
||||
url: http://fr.ivolo.us
|
||||
body: this plugin rocks!
|
||||
tags_002:
|
||||
id: "2"
|
||||
name: yuanyiz
|
||||
email: no1@nowhere.com
|
||||
url: http://letrails.cn
|
||||
body: this plugin has saved my life
|
||||
28
vendor/plugins/has_many_polymorphs/generators/commenting/templates/migration.rb
vendored
Normal file
28
vendor/plugins/has_many_polymorphs/generators/commenting/templates/migration.rb
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
# A migration to add tables for Comment and Commenting. This file is automatically generated and added to your app if you run the commenting generator.
|
||||
|
||||
class CreateCommentsAndCommentings < ActiveRecord::Migration
|
||||
|
||||
# Add the new tables.
|
||||
def self.up
|
||||
create_table :comments do |t|
|
||||
t.column :name, :string, :null => false
|
||||
t.column :url, :string
|
||||
t.column :email, :string
|
||||
t.column :body, :text
|
||||
end
|
||||
|
||||
create_table :commentings do |t|
|
||||
t.column :<%= parent_association_name -%>_id, :integer, :null => false
|
||||
t.column :commentable_id, :integer, :null => false
|
||||
t.column :commentable_type, :string, :null => false
|
||||
end
|
||||
end
|
||||
|
||||
# Remove the tables.
|
||||
def self.down
|
||||
drop_table :comments
|
||||
drop_table :commentings
|
||||
end
|
||||
|
||||
end
|
||||
95
vendor/plugins/has_many_polymorphs/generators/tagging/tagging_generator.rb
vendored
Normal file
95
vendor/plugins/has_many_polymorphs/generators/tagging/tagging_generator.rb
vendored
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
require 'ruby-debug' and Debugger.start if ENV['USER'] == 'eweaver'
|
||||
|
||||
class TaggingGenerator < Rails::Generator::NamedBase
|
||||
default_options :skip_migration => false
|
||||
default_options :self_referential => false
|
||||
attr_reader :parent_association_name
|
||||
attr_reader :taggable_models
|
||||
|
||||
def initialize(runtime_args, runtime_options = {})
|
||||
@parent_association_name = (runtime_args.include?("--self-referential") ? "tagger" : "tag")
|
||||
@taggable_models = runtime_args.reject{|opt| opt =~ /^--/}.map do |taggable|
|
||||
":" + taggable.underscore.pluralize
|
||||
end
|
||||
@taggable_models += [":tags"] if runtime_args.include?("--self-referential")
|
||||
@taggable_models.uniq!
|
||||
|
||||
verify @taggable_models
|
||||
hacks
|
||||
runtime_args.unshift("placeholder")
|
||||
super
|
||||
end
|
||||
|
||||
def verify models
|
||||
puts "** Warning: only one taggable model specified; tests may not run properly." if models.size < 2
|
||||
models.each do |model|
|
||||
model = model[1..-1].classify
|
||||
next if model == "Tag" # don't load ourselves when --self-referential is used
|
||||
self.class.const_get(model) rescue puts "** Error: model #{model[1..-1].classify} could not be loaded." or exit
|
||||
end
|
||||
end
|
||||
|
||||
def hacks
|
||||
# add the extension require in environment.rb
|
||||
phrase = "require 'tagging_extensions'"
|
||||
filename = "#{RAILS_ROOT}/config/environment.rb"
|
||||
unless (open(filename) do |file|
|
||||
file.grep(/#{Regexp.escape phrase}/).any?
|
||||
end)
|
||||
open(filename, 'a+') do |file|
|
||||
file.puts "\n" + phrase + "\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def manifest
|
||||
record do |m|
|
||||
m.class_collisions class_path, class_name, "#{class_name}Test"
|
||||
|
||||
m.directory File.join('app/models', class_path)
|
||||
m.directory File.join('test/unit', class_path)
|
||||
m.directory File.join('test/fixtures', class_path)
|
||||
m.directory File.join('test/fixtures', class_path)
|
||||
m.directory File.join('lib')
|
||||
|
||||
m.template 'tag.rb', File.join('app/models', class_path, "tag.rb")
|
||||
m.template 'tag_test.rb', File.join('test/unit', class_path, "tag_test.rb")
|
||||
m.template 'tags.yml', File.join('test/fixtures', class_path, "tags.yml")
|
||||
|
||||
m.template 'tagging.rb', File.join('app/models', class_path, "tagging.rb")
|
||||
m.template 'tagging_test.rb', File.join('test/unit', class_path, "tagging_test.rb")
|
||||
m.template 'taggings.yml', File.join('test/fixtures', class_path, "taggings.yml")
|
||||
|
||||
m.template 'tagging_extensions.rb', File.join('lib', 'tagging_extensions.rb')
|
||||
|
||||
unless options[:skip_migration]
|
||||
m.migration_template 'migration.rb', 'db/migrate',
|
||||
:migration_file_name => "create_tags_and_taggings"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
def banner
|
||||
"Usage: #{$0} generate tagging [TaggableModelA TaggableModelB ...]"
|
||||
end
|
||||
|
||||
def add_options!(opt)
|
||||
opt.separator ''
|
||||
opt.separator 'Options:'
|
||||
opt.on("--skip-migration",
|
||||
"Don't generate a migration file for this model") { |v| options[:skip_migration] = v }
|
||||
opt.on("--self-referential",
|
||||
"Allow tags to tag themselves.") { |v| options[:self_referential] = v }
|
||||
end
|
||||
|
||||
# Useful for generating tests/fixtures
|
||||
def model_one
|
||||
taggable_models[0][1..-1].classify
|
||||
end
|
||||
|
||||
def model_two
|
||||
taggable_models[1][1..-1].classify rescue model_one
|
||||
end
|
||||
end
|
||||
28
vendor/plugins/has_many_polymorphs/generators/tagging/templates/migration.rb
vendored
Normal file
28
vendor/plugins/has_many_polymorphs/generators/tagging/templates/migration.rb
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
# A migration to add tables for Tag and Tagging. This file is automatically generated and added to your app if you run the tagging generator included with has_many_polymorphs.
|
||||
|
||||
class CreateTagsAndTaggings < ActiveRecord::Migration
|
||||
|
||||
# Add the new tables.
|
||||
def self.up
|
||||
create_table :tags do |t|
|
||||
t.column :name, :string, :null => false
|
||||
end
|
||||
add_index :tags, :name, :unique => true
|
||||
|
||||
create_table :taggings do |t|
|
||||
t.column :<%= parent_association_name -%>_id, :integer, :null => false
|
||||
t.column :taggable_id, :integer, :null => false
|
||||
t.column :taggable_type, :string, :null => false
|
||||
# t.column :position, :integer # Uncomment this if you need to use <tt>acts_as_list</tt>.
|
||||
end
|
||||
add_index :taggings, [:<%= parent_association_name -%>_id, :taggable_id, :taggable_type], :unique => true
|
||||
end
|
||||
|
||||
# Remove the tables.
|
||||
def self.down
|
||||
drop_table :tags
|
||||
drop_table :taggings
|
||||
end
|
||||
|
||||
end
|
||||
39
vendor/plugins/has_many_polymorphs/generators/tagging/templates/tag.rb
vendored
Normal file
39
vendor/plugins/has_many_polymorphs/generators/tagging/templates/tag.rb
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
# The Tag model. This model is automatically generated and added to your app if you run the tagging generator included with has_many_polymorphs.
|
||||
|
||||
class Tag < ActiveRecord::Base
|
||||
|
||||
DELIMITER = " " # Controls how to split and join tagnames from strings. You may need to change the <tt>validates_format_of parameters</tt> if you change this.
|
||||
|
||||
# If database speed becomes an issue, you could remove these validations and rescue the ActiveRecord database constraint errors instead.
|
||||
validates_presence_of :name
|
||||
validates_uniqueness_of :name, :case_sensitive => false
|
||||
|
||||
# Change this validation if you need more complex tag names.
|
||||
validates_format_of :name, :with => /^[a-zA-Z0-9\_\-]+$/, :message => "can not contain special characters"
|
||||
|
||||
# Set up the polymorphic relationship.
|
||||
has_many_polymorphs :taggables,
|
||||
:from => [<%= taggable_models.join(", ") %>],
|
||||
:through => :taggings,
|
||||
:dependent => :destroy,
|
||||
<% if options[:self_referential] -%> :as => :<%= parent_association_name -%>,
|
||||
<% end -%>
|
||||
:skip_duplicates => false,
|
||||
:parent_extend => proc {
|
||||
# Defined on the taggable models, not on Tag itself. Return the tagnames associated with this record as a string.
|
||||
def to_s
|
||||
self.map(&:name).sort.join(Tag::DELIMITER)
|
||||
end
|
||||
}
|
||||
|
||||
# Callback to strip extra spaces from the tagname before saving it. If you allow tags to be renamed later, you might want to use the <tt>before_save</tt> callback instead.
|
||||
def before_create
|
||||
self.name = name.downcase.strip.squeeze(" ")
|
||||
end
|
||||
|
||||
# Tag::Error class. Raised by ActiveRecord::Base::TaggingExtensions if something goes wrong.
|
||||
class Error < StandardError
|
||||
end
|
||||
|
||||
end
|
||||
10
vendor/plugins/has_many_polymorphs/generators/tagging/templates/tag_test.rb
vendored
Normal file
10
vendor/plugins/has_many_polymorphs/generators/tagging/templates/tag_test.rb
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class TagTest < Test::Unit::TestCase
|
||||
fixtures :tags, :taggings, <%= taggable_models[0..1].join(", ") -%>
|
||||
|
||||
def test_to_s
|
||||
assert_equal "delicious sexy", <%= model_two -%>.find(2).tags.to_s
|
||||
end
|
||||
|
||||
end
|
||||
16
vendor/plugins/has_many_polymorphs/generators/tagging/templates/tagging.rb
vendored
Normal file
16
vendor/plugins/has_many_polymorphs/generators/tagging/templates/tagging.rb
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
# The Tagging join model. This model is automatically generated and added to your app if you run the tagging generator included with has_many_polymorphs.
|
||||
|
||||
class Tagging < ActiveRecord::Base
|
||||
|
||||
belongs_to :<%= parent_association_name -%><%= ", :foreign_key => \"#{parent_association_name}_id\", :class_name => \"Tag\"" if options[:self_referential] %>
|
||||
belongs_to :taggable, :polymorphic => true
|
||||
|
||||
# If you also need to use <tt>acts_as_list</tt>, you will have to manage the tagging positions manually by creating decorated join records when you associate Tags with taggables.
|
||||
# acts_as_list :scope => :taggable
|
||||
|
||||
# This callback makes sure that an orphaned <tt>Tag</tt> is deleted if it no longer tags anything.
|
||||
def before_destroy
|
||||
<%= parent_association_name -%>.destroy_without_callbacks if <%= parent_association_name -%> and <%= parent_association_name -%>.taggings.count == 1
|
||||
end
|
||||
end
|
||||
106
vendor/plugins/has_many_polymorphs/generators/tagging/templates/tagging_extensions.rb
vendored
Normal file
106
vendor/plugins/has_many_polymorphs/generators/tagging/templates/tagging_extensions.rb
vendored
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
|
||||
class ActiveRecord::Base #:nodoc:
|
||||
|
||||
# These extensions make models taggable. This file is automatically generated and required by your app if you run the tagging generator included with has_many_polymorphs.
|
||||
module TaggingExtensions
|
||||
|
||||
# Add tags to <tt>self</tt>. Accepts a string of tagnames, an array of tagnames, an array of ids, or an array of Tags.
|
||||
#
|
||||
# We need to avoid name conflicts with the built-in ActiveRecord association methods, thus the underscores.
|
||||
def _add_tags incoming
|
||||
taggable?(true)
|
||||
tag_cast_to_string(incoming).each do |tag_name|
|
||||
begin
|
||||
tag = Tag.find_or_create_by_name(tag_name)
|
||||
raise Tag::Error, "tag could not be saved: #{tag_name}" if tag.new_record?
|
||||
tag.taggables << self
|
||||
rescue ActiveRecord::StatementInvalid => e
|
||||
raise unless e.to_s =~ /duplicate/i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Removes tags from <tt>self</tt>. Accepts a string of tagnames, an array of tagnames, an array of ids, or an array of Tags.
|
||||
def _remove_tags outgoing
|
||||
taggable?(true)
|
||||
outgoing = tag_cast_to_string(outgoing)
|
||||
<% if options[:self_referential] %>
|
||||
# because of http://dev.rubyonrails.org/ticket/6466
|
||||
taggings.destroy(*(taggings.find(:all, :include => :<%= parent_association_name -%>).select do |tagging|
|
||||
outgoing.include? tagging.<%= parent_association_name -%>.name
|
||||
end))
|
||||
<% else -%>
|
||||
<%= parent_association_name -%>s.delete(*(<%= parent_association_name -%>s.select do |tag|
|
||||
outgoing.include? tag.name
|
||||
end))
|
||||
<% end -%>
|
||||
end
|
||||
|
||||
# Returns the tags on <tt>self</tt> as a string.
|
||||
def tag_list
|
||||
# Redefined later to avoid an RDoc parse error.
|
||||
end
|
||||
|
||||
# Replace the existing tags on <tt>self</tt>. Accepts a string of tagnames, an array of tagnames, an array of ids, or an array of Tags.
|
||||
def tag_with list
|
||||
#:stopdoc:
|
||||
taggable?(true)
|
||||
list = tag_cast_to_string(list)
|
||||
|
||||
# Transactions may not be ideal for you here; be aware.
|
||||
Tag.transaction do
|
||||
current = <%= parent_association_name -%>s.map(&:name)
|
||||
_add_tags(list - current)
|
||||
_remove_tags(current - list)
|
||||
end
|
||||
|
||||
self
|
||||
#:startdoc:
|
||||
end
|
||||
|
||||
# Returns the tags on <tt>self</tt> as a string.
|
||||
def tag_list #:nodoc:
|
||||
#:stopdoc:
|
||||
taggable?(true)
|
||||
<%= parent_association_name -%>s.reload
|
||||
<%= parent_association_name -%>s.to_s
|
||||
#:startdoc:
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def tag_cast_to_string obj #:nodoc:
|
||||
case obj
|
||||
when Array
|
||||
obj.map! do |item|
|
||||
case item
|
||||
when /^\d+$/, Fixnum then Tag.find(item).name # This will be slow if you use ids a lot.
|
||||
when Tag then item.name
|
||||
when String then item
|
||||
else
|
||||
raise "Invalid type"
|
||||
end
|
||||
end
|
||||
when String
|
||||
obj = obj.split(Tag::DELIMITER).map do |tag_name|
|
||||
tag_name.strip.squeeze(" ")
|
||||
end
|
||||
else
|
||||
raise "Invalid object of class #{obj.class} as tagging method parameter"
|
||||
end.flatten.compact.map(&:downcase).uniq
|
||||
end
|
||||
|
||||
# Check if a model is in the :taggables target list. The alternative to this check is to explicitly include a TaggingMethods module (which you would create) in each target model.
|
||||
def taggable?(should_raise = false) #:nodoc:
|
||||
unless flag = respond_to?(:<%= parent_association_name -%>s)
|
||||
raise "#{self.class} is not a taggable model" if should_raise
|
||||
end
|
||||
flag
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
include TaggingExtensions
|
||||
|
||||
end
|
||||
|
||||
62
vendor/plugins/has_many_polymorphs/generators/tagging/templates/tagging_test.rb
vendored
Normal file
62
vendor/plugins/has_many_polymorphs/generators/tagging/templates/tagging_test.rb
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class TaggingTest < Test::Unit::TestCase
|
||||
fixtures :taggings, :tags, <%= taggable_models[0..1].join(", ") -%>
|
||||
|
||||
def setup
|
||||
@obj1 = <%= model_two %>.find(1)
|
||||
@obj2 = <%= model_two %>.find(2)
|
||||
<% if taggable_models.size > 1 -%>
|
||||
@obj3 = <%= model_one -%>.find(1)
|
||||
<% end -%>
|
||||
@tag1 = Tag.find(1)
|
||||
@tag2 = Tag.find(2)
|
||||
@tagging1 = Tagging.find(1)
|
||||
end
|
||||
|
||||
def test_tag_with
|
||||
@obj2.tag_with "dark columbian"
|
||||
assert_equal "columbian dark", @obj2.tag_list
|
||||
end
|
||||
|
||||
<% if options[:self_referential] -%>
|
||||
def test_self_referential_tag_with
|
||||
@tag1.tag_with [1, 2]
|
||||
assert @tag1.tags.include?(@tag1)
|
||||
assert !@tag2.tags.include?(@tag1)
|
||||
end
|
||||
|
||||
<% end -%>
|
||||
def test__add_tags
|
||||
@obj1._add_tags "porter longneck"
|
||||
assert Tag.find_by_name("porter").taggables.include?(@obj1)
|
||||
assert Tag.find_by_name("longneck").taggables.include?(@obj1)
|
||||
assert_equal "delicious longneck porter", @obj1.tag_list
|
||||
|
||||
@obj1._add_tags [2]
|
||||
assert_equal "delicious longneck porter sexy", @obj1.tag_list
|
||||
end
|
||||
|
||||
def test__remove_tags
|
||||
@obj2._remove_tags ["2", @tag1]
|
||||
assert @obj2.tags.empty?
|
||||
end
|
||||
|
||||
def test_tag_list
|
||||
assert_equal "delicious sexy", @obj2.tag_list
|
||||
end
|
||||
|
||||
def test_taggable
|
||||
assert_raises(RuntimeError) do
|
||||
@tagging1.send(:taggable?, true)
|
||||
end
|
||||
assert !@tagging1.send(:taggable?)
|
||||
<% if taggable_models.size > 1 -%>
|
||||
assert @obj3.send(:taggable?)
|
||||
<% end -%>
|
||||
<% if options[:self_referential] -%>
|
||||
assert @tag1.send(:taggable?)
|
||||
<% end -%>
|
||||
end
|
||||
|
||||
end
|
||||
23
vendor/plugins/has_many_polymorphs/generators/tagging/templates/taggings.yml
vendored
Normal file
23
vendor/plugins/has_many_polymorphs/generators/tagging/templates/taggings.yml
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
<% if taggable_models.size > 1 -%>
|
||||
taggings_003:
|
||||
<%= parent_association_name -%>_id: "2"
|
||||
id: "3"
|
||||
taggable_type: <%= model_one %>
|
||||
taggable_id: "1"
|
||||
<% end -%>
|
||||
taggings_004:
|
||||
<%= parent_association_name -%>_id: "2"
|
||||
id: "4"
|
||||
taggable_type: <%= model_two %>
|
||||
taggable_id: "2"
|
||||
taggings_001:
|
||||
<%= parent_association_name -%>_id: "1"
|
||||
id: "1"
|
||||
taggable_type: <%= model_two %>
|
||||
taggable_id: "1"
|
||||
taggings_002:
|
||||
<%= parent_association_name -%>_id: "1"
|
||||
id: "2"
|
||||
taggable_type: <%= model_two %>
|
||||
taggable_id: "2"
|
||||
7
vendor/plugins/has_many_polymorphs/generators/tagging/templates/tags.yml
vendored
Normal file
7
vendor/plugins/has_many_polymorphs/generators/tagging/templates/tags.yml
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
tags_001:
|
||||
name: delicious
|
||||
id: "1"
|
||||
tags_002:
|
||||
name: sexy
|
||||
id: "2"
|
||||
Loading…
Add table
Add a link
Reference in a new issue