/
authenticated_generator.rb
262 lines (231 loc) · 11.5 KB
/
authenticated_generator.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
require 'restful_authentication/rails_commands'
class AuthenticatedGenerator < Rails::Generator::NamedBase
default_options :skip_migration => false,
:include_activation => false
attr_reader :controller_name,
:controller_class_path,
:controller_file_path,
:controller_class_nesting,
:controller_class_nesting_depth,
:controller_class_name,
:controller_singular_name,
:controller_plural_name,
:controller_file_name
alias_method :controller_table_name, :controller_plural_name
attr_reader :model_controller_name,
:model_controller_class_path,
:model_controller_file_path,
:model_controller_class_nesting,
:model_controller_class_nesting_depth,
:model_controller_class_name,
:model_controller_singular_name,
:model_controller_plural_name
alias_method :model_controller_file_name, :model_controller_singular_name
alias_method :model_controller_table_name, :model_controller_plural_name
def initialize(runtime_args, runtime_options = {})
super
@rspec = has_rspec?
@controller_name = args.shift || 'sessions'
@model_controller_name = @name.pluralize
# sessions controller
base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
@controller_class_name_without_nesting, @controller_file_name, @controller_plural_name = inflect_names(base_name)
@controller_singular_name = @controller_file_name.singularize
if @controller_class_nesting.empty?
@controller_class_name = @controller_class_name_without_nesting
else
@controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
end
# model controller
base_name, @model_controller_class_path, @model_controller_file_path, @model_controller_class_nesting, @model_controller_class_nesting_depth = extract_modules(@model_controller_name)
@model_controller_class_name_without_nesting, @model_controller_singular_name, @model_controller_plural_name = inflect_names(base_name)
if @model_controller_class_nesting.empty?
@model_controller_class_name = @model_controller_class_name_without_nesting
else
@model_controller_class_name = "#{@model_controller_class_nesting}::#{@model_controller_class_name_without_nesting}"
end
end
def manifest
recorded_session = record do |m|
# Check for class naming collisions.
m.class_collisions controller_class_path, "#{controller_class_name}Controller", # Sessions Controller
"#{controller_class_name}Helper"
m.class_collisions model_controller_class_path, "#{model_controller_class_name}Controller", # Model Controller
"#{model_controller_class_name}Helper"
m.class_collisions class_path, "#{class_name}", "#{class_name}Mailer", "#{class_name}MailerTest", "#{class_name}Observer"
m.class_collisions [], 'AuthenticatedSystem', 'AuthenticatedTestHelper'
# Controller, helper, views, and test directories.
m.directory File.join('app/models', class_path)
m.directory File.join('app/controllers', controller_class_path)
m.directory File.join('app/controllers', model_controller_class_path)
m.directory File.join('app/helpers', controller_class_path)
m.directory File.join('app/views', controller_class_path, controller_file_name)
m.directory File.join('app/views', class_path, "#{file_name}_mailer") if options[:include_activation]
m.directory File.join('app/controllers', model_controller_class_path)
m.directory File.join('app/helpers', model_controller_class_path)
m.directory File.join('app/views', model_controller_class_path, model_controller_file_name)
if @rspec
m.directory File.join('spec/controllers', controller_class_path)
m.directory File.join('spec/controllers', model_controller_class_path)
m.directory File.join('spec/models', class_path)
m.directory File.join('spec/fixtures', class_path)
else
m.directory File.join('test/functional', controller_class_path)
m.directory File.join('test/functional', model_controller_class_path)
m.directory File.join('test/unit', class_path)
end
m.template 'model.rb',
File.join('app/models',
class_path,
"#{file_name}.rb")
if options[:include_activation]
%w( mailer observer ).each do |model_type|
m.template "#{model_type}.rb", File.join('app/models',
class_path,
"#{file_name}_#{model_type}.rb")
end
end
m.template 'controller.rb',
File.join('app/controllers',
controller_class_path,
"#{controller_file_name}_controller.rb")
m.template 'model_controller.rb',
File.join('app/controllers',
model_controller_class_path,
"#{model_controller_file_name}_controller.rb")
m.template 'authenticated_system.rb',
File.join('lib', 'authenticated_system.rb')
m.template 'authenticated_test_helper.rb',
File.join('lib', 'authenticated_test_helper.rb')
if @rspec
m.template 'functional_spec.rb',
File.join('spec/controllers',
controller_class_path,
"#{controller_file_name}_controller_spec.rb")
m.template 'model_functional_spec.rb',
File.join('spec/controllers',
model_controller_class_path,
"#{model_controller_file_name}_controller_spec.rb")
m.template 'unit_spec.rb',
File.join('spec/models',
class_path,
"#{file_name}_spec.rb")
m.template 'fixtures.yml',
File.join('spec/fixtures',
"#{table_name}.yml")
else
m.template 'functional_test.rb',
File.join('test/functional',
controller_class_path,
"#{controller_file_name}_controller_test.rb")
m.template 'model_functional_test.rb',
File.join('test/functional',
model_controller_class_path,
"#{model_controller_file_name}_controller_test.rb")
m.template 'unit_test.rb',
File.join('test/unit',
class_path,
"#{file_name}_test.rb")
if options[:include_activation]
m.template 'mailer_test.rb', File.join('test/unit', class_path, "#{file_name}_mailer_test.rb")
end
m.template 'fixtures.yml',
File.join('test/fixtures',
"#{table_name}.yml")
end
m.template 'helper.rb',
File.join('app/helpers',
controller_class_path,
"#{controller_file_name}_helper.rb")
m.template 'model_helper.rb',
File.join('app/helpers',
model_controller_class_path,
"#{model_controller_file_name}_helper.rb")
# Controller templates
m.template 'login.html.erb', File.join('app/views', controller_class_path, controller_file_name, "new.html.erb")
m.template 'signup.html.erb', File.join('app/views', model_controller_class_path, model_controller_file_name, "new.html.erb")
if options[:include_activation]
# Mailer templates
%w( activation signup_notification ).each do |action|
m.template "#{action}.html.erb",
File.join('app/views', "#{file_name}_mailer", "#{action}.html.erb")
end
end
unless options[:skip_migration]
m.migration_template 'migration.rb', 'db/migrate', :assigns => {
:migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}"
}, :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
end
m.route_resource controller_singular_name
m.route_resources model_controller_plural_name
end
action = nil
action = $0.split("/")[1]
case action
when "generate"
puts
puts ("-" * 70)
puts "Don't forget to:"
puts
if options[:include_activation]
puts " map.activate '/activate/:activation_code', :controller => '#{model_controller_file_name}', :action => 'activate'"
puts
puts " - add an observer to config/environment.rb"
puts " config.active_record.observers = :#{file_name}_observer"
puts
end
if options[:stateful]
puts "Also, don't forget to install the acts_as_state_machine plugin and set your resource:"
puts
puts " svn co http://elitists.textdriven.com/svn/plugins/acts_as_state_machine/trunk vendor/plugins/acts_as_state_machine"
puts
puts %w(map.resources :#{model_controller_file_name}, :member => { :suspend => :put, :unsuspend => :put, :purge => :delete })
puts
end
puts "Try these for some familiar login URLs if you like:"
puts
puts %(map.activate '/activate/:activation_code', :controller => '#{model_controller_file_name}', :action => 'activate', :activation_code => nil)
puts %(map.signup '/signup', :controller => '#{model_controller_file_name}', :action => 'new')
puts %(map.login '/login', :controller => '#{controller_file_name}', :action => 'new')
puts %(map.logout '/logout', :controller => '#{controller_file_name}', :action => 'destroy')
puts
puts ("-" * 70)
puts
when "destroy"
puts
puts ("-" * 70)
puts
puts "Thanks for using restful_authentication"
puts
puts "Don't forget to comment out the observer line in environment.rb"
puts " (This was optional so it may not even be there)"
puts " # config.active_record.observers = :#{file_name}_observer"
puts
puts ("-" * 70)
puts
else
puts
end
recorded_session
end
def has_rspec?
options[:rspec] || (File.exist?('spec') && File.directory?('spec'))
end
protected
# Override with your own usage banner.
def banner
"Usage: #{$0} authenticated ModelName [ControllerName]"
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("--include-activation",
"Generate signup 'activation code' confirmation via email") { |v| options[:include_activation] = true }
opt.on("--stateful",
"Use acts_as_state_machine. Assumes --include-activation") { |v| options[:include_activation] = options[:stateful] = true }
opt.on("--rspec",
"Force rspec mode (checks for RAILS_ROOT/spec by default)") { |v| options[:rspec] = true }
end
end