Add the has_many_polymorphs plugin
[cs356-p2-videostore.git] / vendor / plugins / has_many_polymorphs / generators / tagging / tagging_generator.rb
1 require 'ruby-debug' and Debugger.start if ENV['USER'] == 'eweaver'
2
3 class TaggingGenerator < Rails::Generator::NamedBase
4   default_options :skip_migration => false
5   default_options :self_referential => false
6   attr_reader :parent_association_name
7   attr_reader :taggable_models
8
9   def initialize(runtime_args, runtime_options = {})
10     @parent_association_name = (runtime_args.include?("--self-referential") ? "tagger" : "tag")
11     @taggable_models = runtime_args.reject{|opt| opt =~ /^--/}.map do |taggable|
12       ":" + taggable.underscore.pluralize
13     end
14     @taggable_models += [":tags"] if runtime_args.include?("--self-referential") 
15     @taggable_models.uniq!
16         
17     verify @taggable_models
18     hacks     
19     runtime_args.unshift("placeholder")
20     super
21   end
22   
23   def verify models
24     puts "** Warning: only one taggable model specified; tests may not run properly." if models.size < 2
25     models.each do |model|
26       model = model[1..-1].classify
27       next if model == "Tag" # don't load ourselves when --self-referential is used
28       self.class.const_get(model) rescue puts "** Error: model #{model[1..-1].classify} could not be loaded." or exit
29     end
30   end
31   
32   def hacks    
33     # add the extension require in environment.rb
34     phrase = "require 'tagging_extensions'"
35     filename = "#{RAILS_ROOT}/config/environment.rb"
36     unless (open(filename) do |file|
37       file.grep(/#{Regexp.escape phrase}/).any?
38     end)
39       open(filename, 'a+') do |file|
40         file.puts "\n" + phrase + "\n"
41       end
42     end
43   end
44   
45   def manifest
46     record do |m|
47       m.class_collisions class_path, class_name, "#{class_name}Test"
48
49       m.directory File.join('app/models', class_path)
50       m.directory File.join('test/unit', class_path)
51       m.directory File.join('test/fixtures', class_path)
52       m.directory File.join('test/fixtures', class_path)
53       m.directory File.join('lib')
54
55       m.template 'tag.rb', File.join('app/models', class_path, "tag.rb")
56       m.template 'tag_test.rb', File.join('test/unit', class_path, "tag_test.rb")
57       m.template 'tags.yml', File.join('test/fixtures', class_path, "tags.yml")
58       
59       m.template 'tagging.rb', File.join('app/models', class_path, "tagging.rb")
60       m.template 'tagging_test.rb', File.join('test/unit', class_path, "tagging_test.rb")
61       m.template 'taggings.yml', File.join('test/fixtures', class_path, "taggings.yml")
62       
63       m.template 'tagging_extensions.rb', File.join('lib', 'tagging_extensions.rb')
64
65       unless options[:skip_migration]
66         m.migration_template 'migration.rb', 'db/migrate',
67           :migration_file_name => "create_tags_and_taggings"
68       end
69       
70     end
71   end
72
73   protected
74     def banner
75       "Usage: #{$0} generate tagging [TaggableModelA TaggableModelB ...]"
76     end
77
78     def add_options!(opt)
79       opt.separator ''
80       opt.separator 'Options:'
81       opt.on("--skip-migration", 
82              "Don't generate a migration file for this model") { |v| options[:skip_migration] = v }
83       opt.on("--self-referential",
84              "Allow tags to tag themselves.") { |v| options[:self_referential] = v }
85     end
86     
87     # Useful for generating tests/fixtures
88     def model_one
89       taggable_models[0][1..-1].classify
90     end
91     
92     def model_two
93       taggable_models[1][1..-1].classify rescue model_one
94     end
95 end