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