aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb
diff options
context:
space:
mode:
Diffstat (limited to 'railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb')
-rw-r--r--railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb161
1 files changed, 161 insertions, 0 deletions
diff --git a/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb b/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb
new file mode 100644
index 0000000000..4445995b46
--- /dev/null
+++ b/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb
@@ -0,0 +1,161 @@
+class ScaffoldingSandbox
+ include ActionView::Helpers::ActiveRecordHelper
+
+ attr_accessor :form_action, :singular_name, :suffix, :model_instance
+
+ def sandbox_binding
+ binding
+ end
+end
+
+class ActionView::Helpers::InstanceTag
+ def to_input_field_tag(field_type, options={})
+ field_meth = "#{field_type}_field"
+ "<%= #{field_meth} '#{@object_name}', '#{@method_name}' #{options.empty? ? '' : ', '+options.inspect} %>"
+ end
+
+ def to_text_area_tag(options = {})
+ "<%= text_area '#{@object_name}', '#{@method_name}' #{options.empty? ? '' : ', '+ options.inspect} %>"
+ end
+
+ def to_date_select_tag(options = {})
+ "<%= date_select '#{@object_name}', '#{@method_name}' #{options.empty? ? '' : ', '+ options.inspect} %>"
+ end
+
+ def to_datetime_select_tag(options = {})
+ "<%= datetime_select '#{@object_name}', '#{@method_name}' #{options.empty? ? '' : ', '+ options.inspect} %>"
+ end
+end
+
+class ScaffoldGenerator < Rails::Generator::NamedBase
+ attr_reader :controller_name,
+ :controller_class_path,
+ :controller_class_nesting,
+ :controller_class_name,
+ :controller_singular_name,
+ :controller_plural_name
+ alias_method :controller_file_name, :controller_singular_name
+ alias_method :controller_table_name, :controller_plural_name
+
+ def initialize(runtime_args, runtime_options = {})
+ super
+ @controller_name = args.shift || @name.pluralize
+ base_name, @controller_class_path, @controller_class_nesting = extract_modules(@controller_name)
+ @controller_class_name, @controller_singular_name, @controller_plural_name = inflect_names(base_name)
+ end
+
+ def manifest
+ record do |m|
+ # Depend on model generator but skip if the model exists.
+ m.dependency 'model', [@name], :collision => :skip
+
+ # Check for class naming collisions.
+ m.class_collisions "#{controller_class_name}Controller", "#{controller_class_name}ControllerTest", "#{controller_class_name}Helper"
+
+ # Views directory.
+ m.directory File.join('app/views', controller_class_path, controller_file_name)
+
+ # Controller class, functional test, helper, and views.
+ m.template 'controller.rb',
+ File.join('app/controllers',
+ controller_class_path,
+ "#{controller_file_name}_controller.rb")
+
+ m.template 'functional_test.rb',
+ File.join('test/functional',
+ controller_class_path,
+ "#{controller_file_name}_controller_test.rb")
+
+ m.template 'controller:helper.rb',
+ File.join('app/helpers',
+ controller_class_path,
+ "#{controller_file_name}_helper.rb")
+
+ # Layout and stylesheet.
+ m.template 'layout.rhtml', "app/views/layouts/#{controller_file_name}.rhtml"
+ m.template 'style.css', 'public/stylesheets/scaffold.css'
+
+ # Scaffolded views.
+ scaffold_views.each do |action|
+ m.template "view_#{action}.rhtml",
+ File.join('app/views',
+ controller_class_path, controller_file_name,
+ "#{action}.rhtml"),
+ :assigns => { :action => action }
+ end
+
+ # Scaffolded forms.
+ scaffold_forms.each do |action|
+ m.complex_template "view_#{action}.rhtml",
+ File.join('app/views',
+ controller_class_path,
+ controller_file_name,
+ "#{action}.rhtml"),
+ :assigns => { :action => action },
+ :insert => 'form.rhtml',
+ :sandbox => lambda { create_sandbox(action) },
+ :begin_mark => 'form',
+ :end_mark => 'eoform',
+ :mark_id => singular_name
+ end
+
+ # Unscaffolded views.
+ unscaffolded_actions.each do |action|
+ m.template "controller:view.rhtml",
+ File.join('app/views',
+ controller_class_path, controller_file_name,
+ "#{action}.rhtml"),
+ :assigns => { :action => action }
+ end
+ end
+ end
+
+ protected
+ # Override with your own usage banner.
+ def banner
+ "Usage: #{$0} scaffold ModelName [ControllerName] [action, ...]"
+ end
+
+ def scaffold_views
+ %w(list show)
+ end
+
+ def scaffold_forms
+ %w(new edit)
+ end
+
+ def scaffold_actions
+ scaffold_views + %w(index create update destroy)
+ end
+
+ def unscaffolded_actions
+ args - scaffold_actions
+ end
+
+ def suffix
+ "_#{singular_name}" if options[:suffix]
+ end
+
+ def create_sandbox(action)
+ sandbox = ScaffoldingSandbox.new
+ action = if action == 'edit' then 'update' else 'create' end
+ sandbox.form_action = action
+ sandbox.singular_name = singular_name
+ begin
+ sandbox.model_instance = model_instance
+ sandbox.instance_variable_set("@#{singular_name}", sandbox.model_instance)
+ rescue ActiveRecord::StatementInvalid => e
+ logger.error "Before updating scaffolding from new DB schema, try creating a table for your model (#{class_name})"
+ raise SystemExit
+ end
+ sandbox.suffix = suffix
+ sandbox
+ end
+
+ def model_instance
+ unless Object.const_defined?(class_name)
+ Object.const_set(class_name, Class.new(ActiveRecord::Base))
+ end
+ Object.const_get(class_name).new
+ end
+end