has_many_through_generator 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +3 -0
- data/HOWTO +473 -0
- data/MIT-LICENSE +20 -0
- data/README +18 -0
- data/has_many_through_generator.rb +330 -0
- data/templates/controller.rb +116 -0
- data/templates/controller_manytomany.rb +56 -0
- data/templates/fixtures.yml +8 -0
- data/templates/fixtures_manytomany.yml +13 -0
- data/templates/functional_test.rb +78 -0
- data/templates/functional_test_manytomany.rb +75 -0
- data/templates/helper.rb +2 -0
- data/templates/layout.rhtml +15 -0
- data/templates/migration.rb +11 -0
- data/templates/migration_manytomany.rb +12 -0
- data/templates/model.rb +4 -0
- data/templates/model_manytomany.rb +8 -0
- data/templates/partial_form.rhtml +3 -0
- data/templates/stylesheet.css +5 -0
- data/templates/unit_test.rb +67 -0
- data/templates/unit_test_manytomany.rb +68 -0
- data/templates/view_index.rhtml +1 -0
- metadata +67 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2006 Dr Nic Williams
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
*******************************************************************************************
|
2
|
+
** For all documentation see the project website: http://hasmanythrough.rubyforge.org **
|
3
|
+
*******************************************************************************************
|
4
|
+
|
5
|
+
Description:
|
6
|
+
|
7
|
+
Example:
|
8
|
+
./script/generate has_many_throuh User Group
|
9
|
+
./script/generate has_many_throuh User Group Membership
|
10
|
+
|
11
|
+
Both will generate User and Group models and unit tests (if they don't
|
12
|
+
already exist). It will both also generate a third model representing
|
13
|
+
the many-to-many relationship between the two, called UserGroup (first
|
14
|
+
example and Membership (second example).
|
15
|
+
|
16
|
+
It will also generate unit tests for the many-to-many class, and all
|
17
|
+
unit tests will test the relationships between the other two classes.
|
18
|
+
|
@@ -0,0 +1,330 @@
|
|
1
|
+
class Hash
|
2
|
+
# lets through the keys in the argument
|
3
|
+
# >> {:one => 1, :two => 2, :three => 3}.pass(:one)
|
4
|
+
# => {:one=>1}
|
5
|
+
def pass(*keys)
|
6
|
+
tmp = self.clone
|
7
|
+
keys = keys[0] if keys[0].is_a? Array
|
8
|
+
tmp.delete_if {|k,v| ! keys.include?(k) }
|
9
|
+
tmp
|
10
|
+
end
|
11
|
+
|
12
|
+
def merge_with_prefix(prefix, hash)
|
13
|
+
merged = clone
|
14
|
+
hash.each {|key, value| merged.merge!("#{prefix}_#{key}" => value)}
|
15
|
+
merged
|
16
|
+
end
|
17
|
+
|
18
|
+
def merge_with_prefix!(prefix, hash)
|
19
|
+
hash.each {|key, value| merge!("#{prefix}_#{key}" => value)}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class Rails::Generator::Manifest
|
24
|
+
attr_reader :actions
|
25
|
+
|
26
|
+
def copy_actions(manifest)
|
27
|
+
@actions.concat(manifest.actions)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module Rails::Generator::Commands
|
32
|
+
# Create is the premier generator command. It copies files, creates
|
33
|
+
# directories, renders templates, and more.
|
34
|
+
class Create < Base
|
35
|
+
# When creating a migration, it knows to find the first available file in db/migrate and use the migration.rb template.
|
36
|
+
def migration_template(relative_source, relative_destination, template_options = {})
|
37
|
+
migration_directory relative_destination
|
38
|
+
migration_file_name = template_options[:migration_file_name] || file_name
|
39
|
+
if not migration_exists?(migration_file_name)
|
40
|
+
template(relative_source, "#{relative_destination}/#{next_migration_string}_#{migration_file_name}.rb", template_options)
|
41
|
+
else
|
42
|
+
puts "Skipping migration #{migration_file_name}, as already exists: #{existing_migrations(migration_file_name).first}" if migration_exists?(migration_file_name)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
module Rails
|
49
|
+
module Generator
|
50
|
+
class MultiNamedBase < Rails::Generator::Base
|
51
|
+
attr_reader :all_attrs,
|
52
|
+
:name, :class_name, :singular_name, :plural_name, :table_name,
|
53
|
+
:class_path, :file_path, :class_nesting, :class_nesting_depth
|
54
|
+
alias_method :file_name, :singular_name
|
55
|
+
attr_reader :controller_name,
|
56
|
+
:controller_class_path,
|
57
|
+
:controller_file_path,
|
58
|
+
:controller_class_nesting,
|
59
|
+
:controller_class_nesting_depth,
|
60
|
+
:controller_class_name,
|
61
|
+
:controller_singular_name,
|
62
|
+
:controller_plural_name
|
63
|
+
alias_method :controller_file_name, :controller_singular_name
|
64
|
+
alias_method :controller_table_name, :controller_plural_name
|
65
|
+
#alias_method :base_controller_file_path, :controller_file_path
|
66
|
+
|
67
|
+
MODEL_ATTRS = %w(name class_name singular_name plural_name
|
68
|
+
table_name class_path file_path class_nesting
|
69
|
+
class_nesting_depth file_name singular_name)
|
70
|
+
CONTROLLER_ATTRS = %w(controller_name controller_class_path
|
71
|
+
controller_file_path controller_class_nesting
|
72
|
+
controller_class_nesting_depth controller_class_name
|
73
|
+
controller_singular_name controller_plural_name)
|
74
|
+
|
75
|
+
def initialize(runtime_args, runtime_options = {})
|
76
|
+
super
|
77
|
+
|
78
|
+
# Name argument is required.
|
79
|
+
usage if runtime_args.empty? or runtime_args.length < 2
|
80
|
+
|
81
|
+
@all_attrs = {}
|
82
|
+
|
83
|
+
runtime_args.each do |base_name|
|
84
|
+
load_attrs(base_name)
|
85
|
+
assign_names!(base_name)
|
86
|
+
store_attrs(base_name)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
protected
|
91
|
+
def load_attrs(key)
|
92
|
+
all_attrs[key] = {} if not all_attrs[key]
|
93
|
+
MODEL_ATTRS.concat(CONTROLLER_ATTRS).each do |attr|
|
94
|
+
instance_variable_set "@#{attr.to_s}", all_attrs[key][attr]
|
95
|
+
end
|
96
|
+
all_attrs[key]
|
97
|
+
end
|
98
|
+
|
99
|
+
def store_attrs(key)
|
100
|
+
all_attrs[key] = instance_values.pass(MODEL_ATTRS.concat(CONTROLLER_ATTRS))
|
101
|
+
end
|
102
|
+
|
103
|
+
def assign_names!(name)
|
104
|
+
@name = name
|
105
|
+
base_name, @class_path, @file_path, @class_nesting, @class_nesting_depth = extract_modules(@name)
|
106
|
+
@class_name_without_nesting, @singular_name, @plural_name = inflect_names(base_name)
|
107
|
+
@table_name = ActiveRecord::Base.pluralize_table_names ? plural_name : singular_name
|
108
|
+
if @class_nesting.empty?
|
109
|
+
@class_name = @class_name_without_nesting
|
110
|
+
else
|
111
|
+
@class_name = "#{@class_nesting}::#{@class_name_without_nesting}"
|
112
|
+
end
|
113
|
+
|
114
|
+
@controller_name ||= ActiveRecord::Base.pluralize_table_names ? @name.pluralize : @name
|
115
|
+
|
116
|
+
base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
|
117
|
+
@controller_class_name_without_nesting, @controller_singular_name, @controller_plural_name = inflect_names(base_name)
|
118
|
+
|
119
|
+
if @controller_class_nesting.empty?
|
120
|
+
@controller_class_name = @controller_class_name_without_nesting
|
121
|
+
else
|
122
|
+
@controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Extract modules from filesystem-style or ruby-style path:
|
127
|
+
# good/fun/stuff
|
128
|
+
# Good::Fun::Stuff
|
129
|
+
# produce the same results.
|
130
|
+
def extract_modules(name)
|
131
|
+
modules = name.include?('/') ? name.split('/') : name.split('::')
|
132
|
+
name = modules.pop
|
133
|
+
path = modules.map { |m| m.underscore }
|
134
|
+
file_path = (path + [name.underscore]).join('/')
|
135
|
+
nesting = modules.map { |m| m.camelize }.join('::')
|
136
|
+
[name, path, file_path, nesting, modules.size]
|
137
|
+
end
|
138
|
+
|
139
|
+
def inflect_names(name)
|
140
|
+
camel = name.camelize
|
141
|
+
under = camel.underscore
|
142
|
+
plural = under.pluralize
|
143
|
+
[camel, under, plural]
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
class HasManyThroughGenerator < Rails::Generator::MultiNamedBase
|
150
|
+
default_options :skip_migration => false
|
151
|
+
|
152
|
+
attr_reader :models, :manytomany
|
153
|
+
|
154
|
+
def initialize(runtime_args, runtime_options = {})
|
155
|
+
super
|
156
|
+
|
157
|
+
@models = runtime_args[0..1].sort
|
158
|
+
|
159
|
+
if not (@manytomany = runtime_args[2])
|
160
|
+
@manytomany = "#{models[0]}#{models[1]}"
|
161
|
+
load_attrs(@manytomany)
|
162
|
+
assign_names!(@manytomany)
|
163
|
+
store_attrs(@manytomany)
|
164
|
+
end
|
165
|
+
|
166
|
+
first_attrs_orig = all_attrs[@models.first].clone
|
167
|
+
second_attrs_orig = all_attrs[@models.last].clone
|
168
|
+
manytomany_attrs_orig = all_attrs[@manytomany].clone
|
169
|
+
all_attrs[@manytomany].merge_with_prefix!("first", first_attrs_orig)
|
170
|
+
all_attrs[@manytomany].merge!("first_id_column" => "#{first_attrs_orig['singular_name']}_id")
|
171
|
+
all_attrs[@manytomany].merge_with_prefix!("second", second_attrs_orig)
|
172
|
+
all_attrs[@manytomany].merge!("second_id_column" => "#{second_attrs_orig['singular_name']}_id")
|
173
|
+
|
174
|
+
all_attrs[@models.first].merge_with_prefix!("other", second_attrs_orig)
|
175
|
+
all_attrs[@models.last].merge_with_prefix!("other", first_attrs_orig)
|
176
|
+
@models.each {|model| all_attrs[model].merge_with_prefix!("manytomany", manytomany_attrs_orig)}
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
def manifest
|
181
|
+
record do |m|
|
182
|
+
load_attrs(@models.first)
|
183
|
+
|
184
|
+
|
185
|
+
@models.each do |model_name|
|
186
|
+
attrs = load_attrs(model_name)
|
187
|
+
|
188
|
+
# Check for class naming collisions.
|
189
|
+
m.class_collisions class_path, class_name, "#{class_name}Test"
|
190
|
+
|
191
|
+
# Model, test, and fixture directories.
|
192
|
+
m.directory File.join('app/models', class_path)
|
193
|
+
m.directory File.join('test/unit', class_path)
|
194
|
+
m.directory File.join('test/fixtures', class_path)
|
195
|
+
m.directory File.join('app/controllers', controller_class_path)
|
196
|
+
m.directory File.join('app/helpers', controller_class_path)
|
197
|
+
m.directory File.join('app/views/layouts', controller_class_path)
|
198
|
+
m.directory File.join('app/views', controller_class_path, controller_file_name)
|
199
|
+
m.directory File.join('test/functional', controller_class_path)
|
200
|
+
m.directory File.join('public/stylesheets')
|
201
|
+
|
202
|
+
# Model class, unit test, and fixtures.
|
203
|
+
m.template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb"), :assigns => attrs
|
204
|
+
m.template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_test.rb"), :assigns => attrs
|
205
|
+
m.template 'fixtures.yml', File.join('test/fixtures', class_path, "#{table_name}.yml"), :assigns => attrs
|
206
|
+
|
207
|
+
unless options[:skip_migration]
|
208
|
+
m.migration_template 'migration.rb', 'db/migrate', :assigns => attrs.merge({
|
209
|
+
:migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}"
|
210
|
+
}), :migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
|
211
|
+
end
|
212
|
+
|
213
|
+
# Controller class, functional test, helper, and views.
|
214
|
+
m.template 'controller.rb',
|
215
|
+
File.join('app/controllers',
|
216
|
+
controller_class_path,
|
217
|
+
"#{controller_file_name}_controller.rb"),
|
218
|
+
:assigns => attrs
|
219
|
+
|
220
|
+
m.template 'functional_test.rb',
|
221
|
+
File.join('test/functional',
|
222
|
+
controller_class_path,
|
223
|
+
"#{controller_file_name}_controller_test.rb"),
|
224
|
+
:assigns => attrs
|
225
|
+
|
226
|
+
# Scaffolded partials.
|
227
|
+
scaffold_partials.each do |name|
|
228
|
+
m.template "partial_#{name}.rhtml",
|
229
|
+
File.join('app/views',
|
230
|
+
controller_class_path,
|
231
|
+
controller_file_name,
|
232
|
+
"_#{name}.rhtml"),
|
233
|
+
:assigns => attrs
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
attrs = load_attrs(@manytomany)
|
238
|
+
|
239
|
+
# Check for class naming collisions.
|
240
|
+
m.class_collisions class_path, class_name, "#{class_name}Test"
|
241
|
+
|
242
|
+
# Model, test, and fixture directories.
|
243
|
+
m.directory File.join('app/models', class_path)
|
244
|
+
m.directory File.join('test/unit', class_path)
|
245
|
+
m.directory File.join('test/fixtures', class_path)
|
246
|
+
m.directory File.join('app/controllers', controller_class_path)
|
247
|
+
m.directory File.join('app/helpers', controller_class_path)
|
248
|
+
m.directory File.join('app/views/layouts', controller_class_path)
|
249
|
+
m.directory File.join('app/views', controller_class_path, controller_file_name)
|
250
|
+
m.directory File.join('test/functional', controller_class_path)
|
251
|
+
|
252
|
+
# Model class, unit test, and fixtures.
|
253
|
+
m.template 'model_manytomany.rb', File.join('app/models', class_path, "#{file_name}.rb"), :assigns => attrs
|
254
|
+
m.template 'unit_test_manytomany.rb', File.join('test/unit', class_path, "#{file_name}_test.rb"), :assigns => attrs
|
255
|
+
m.template 'fixtures_manytomany.yml', File.join('test/fixtures', class_path, "#{table_name}.yml"), :assigns => attrs
|
256
|
+
|
257
|
+
unless options[:skip_migration]
|
258
|
+
m.migration_template 'migration_manytomany.rb', 'db/migrate',
|
259
|
+
:assigns => attrs.merge({:migration_name => "Create#{class_name.pluralize.gsub(/::/, '')}"}),
|
260
|
+
:migration_file_name => "create_#{file_path.gsub(/\//, '_').pluralize}"
|
261
|
+
end
|
262
|
+
|
263
|
+
# Controller class, functional test, helper, and views.
|
264
|
+
m.template 'controller_manytomany.rb',
|
265
|
+
File.join('app/controllers',
|
266
|
+
controller_class_path,
|
267
|
+
"#{controller_file_name}_controller.rb"),
|
268
|
+
:assigns => attrs
|
269
|
+
m.template 'functional_test_manytomany.rb',
|
270
|
+
File.join('test/functional',
|
271
|
+
controller_class_path,
|
272
|
+
"#{controller_file_name}_controller_test.rb"),
|
273
|
+
:assigns => attrs
|
274
|
+
|
275
|
+
# Common templates for models and many-to-many model
|
276
|
+
@models.concat([@manytomany]).each do |model_name|
|
277
|
+
attrs = load_attrs(model_name)
|
278
|
+
|
279
|
+
m.template 'helper.rb',
|
280
|
+
File.join('app/helpers',
|
281
|
+
controller_class_path,
|
282
|
+
"#{controller_file_name}_helper.rb"),
|
283
|
+
:assigns => attrs
|
284
|
+
|
285
|
+
# Scaffolded views.
|
286
|
+
scaffold_views.each do |action|
|
287
|
+
m.template "view_#{action}.rhtml",
|
288
|
+
File.join('app/views',
|
289
|
+
controller_class_path,
|
290
|
+
controller_file_name,
|
291
|
+
"#{action}.rhtml"),
|
292
|
+
:assigns => attrs.merge({ :action => action })
|
293
|
+
end
|
294
|
+
# Layout and stylesheet.
|
295
|
+
m.template 'layout.rhtml',
|
296
|
+
File.join('app/views/layouts',
|
297
|
+
controller_class_path,
|
298
|
+
"#{controller_file_name}.rhtml"),
|
299
|
+
:assigns => attrs
|
300
|
+
|
301
|
+
m.template 'stylesheet.css',
|
302
|
+
File.join('public/stylesheets',
|
303
|
+
controller_class_path,
|
304
|
+
"#{controller_file_name}.css"),
|
305
|
+
:assigns => attrs
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
protected
|
311
|
+
def banner
|
312
|
+
"Usage: #{$0} has_many_through ModelName1 ModelName2 [ManyToManyModelName]"
|
313
|
+
end
|
314
|
+
|
315
|
+
def scaffold_views
|
316
|
+
%w( index )
|
317
|
+
end
|
318
|
+
|
319
|
+
def scaffold_partials
|
320
|
+
%w( form )
|
321
|
+
end
|
322
|
+
|
323
|
+
def add_options!(opt)
|
324
|
+
opt.separator ''
|
325
|
+
opt.separator 'Options:'
|
326
|
+
opt.on("--skip-migration",
|
327
|
+
"Don't generate a migration file for this model") { |v| options[:skip_migration] = v }
|
328
|
+
end
|
329
|
+
|
330
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
class <%= controller_class_name %>Controller < ApplicationController
|
2
|
+
|
3
|
+
def index
|
4
|
+
end
|
5
|
+
|
6
|
+
def new
|
7
|
+
@<%= singular_name %> = <%= class_name %>.new
|
8
|
+
@successful = true
|
9
|
+
|
10
|
+
respond_to do |type|
|
11
|
+
type.html do
|
12
|
+
if @successful
|
13
|
+
@options = { :action => "create" }
|
14
|
+
render :partial => "form", :layout => true
|
15
|
+
else
|
16
|
+
redirect_to_main
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def create
|
23
|
+
begin
|
24
|
+
@<%= singular_name %> = <%= class_name %>.new(params[:<%= singular_name %>])
|
25
|
+
@successful = @<%= singular_name %>.save
|
26
|
+
rescue
|
27
|
+
flash[:error], @successful = $!.to_s, false
|
28
|
+
end
|
29
|
+
|
30
|
+
flash[:info] = "<%= class_name %> created" if @successful
|
31
|
+
|
32
|
+
respond_to do |type|
|
33
|
+
type.html do
|
34
|
+
if not @successful
|
35
|
+
@options = { :action => "create" }
|
36
|
+
render :partial => "form", :layout => true
|
37
|
+
else
|
38
|
+
redirect_to_main
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def edit
|
45
|
+
begin
|
46
|
+
@<%= singular_name %> = <%= class_name %>.find(params[:id])
|
47
|
+
@successful = !@<%= singular_name %>.nil?
|
48
|
+
rescue
|
49
|
+
flash[:error], @successful = $!.to_s, false
|
50
|
+
end
|
51
|
+
|
52
|
+
respond_to do |type|
|
53
|
+
type.html do
|
54
|
+
if @successful
|
55
|
+
@options = { :action => "update", :id => params[:id] }
|
56
|
+
render :partial => "form", :layout => true
|
57
|
+
else
|
58
|
+
redirect_to_main
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def update
|
65
|
+
begin
|
66
|
+
@<%= singular_name %> = <%= class_name %>.find(params[:id])
|
67
|
+
@successful = @<%= singular_name %>.update_attributes(params[:<%= singular_name %>])
|
68
|
+
rescue
|
69
|
+
flash[:error], @successful = $!.to_s, false
|
70
|
+
end
|
71
|
+
|
72
|
+
flash[:info] = "<%= class_name %> updated" if @successful
|
73
|
+
|
74
|
+
respond_to do |type|
|
75
|
+
type.html do
|
76
|
+
if not @successful
|
77
|
+
@options = { :action => "update", :id => params[:id] }
|
78
|
+
render :partial => "form", :layout => true
|
79
|
+
else
|
80
|
+
redirect_to_main
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def destroy
|
87
|
+
begin
|
88
|
+
@successful = <%= class_name %>.find(params[:id]).destroy
|
89
|
+
rescue
|
90
|
+
flash[:error], @successful = $!.to_s, false
|
91
|
+
end
|
92
|
+
|
93
|
+
flash[:info] = "<%= class_name %> deleted" if @successful
|
94
|
+
|
95
|
+
respond_to do |type|
|
96
|
+
type.html {return redirect_to_main}
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def cancel
|
101
|
+
@successful = true
|
102
|
+
|
103
|
+
respond_to do |type|
|
104
|
+
type.html {return redirect_to_main}
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
protected
|
109
|
+
def redirect_to_main
|
110
|
+
redirect_to common_redirection
|
111
|
+
end
|
112
|
+
|
113
|
+
def common_redirection
|
114
|
+
{ :action => 'index' }
|
115
|
+
end
|
116
|
+
end
|