Skip to content

Commit

Permalink
Major refactoring. Added support for additional arguments for actions…
Browse files Browse the repository at this point in the history
… and respond_to-formats that is not supported by the Rails-scaffold.
  • Loading branch information
grimen committed Apr 26, 2009
1 parent 5bddcb9 commit 570dbaa
Show file tree
Hide file tree
Showing 23 changed files with 393 additions and 150 deletions.
27 changes: 26 additions & 1 deletion README.textile
Expand Up @@ -4,12 +4,37 @@ h2. SYNOPSIS

...

h2. INSTALLATION
h2. FEATURES

...

h2. INSTALLATION

gem sources -a http://gems.github.com
sudo gem install grimen-dry_scaffold

h2. BASIC USAGE

./script/generate dry_scaffold ModelName [attribute:type attribute:type] [_actions:new,create,...] [_formats:html,json,...] [--skip-resourceful] [--skip-formtastic] [--skip-views] [--skip-helpers] [--skip-tests]

h3. Model Name

...

h3. Model Attributes

...

h3. Controller Actions

...

h3. Controller Formats

...

h3. Options

...

h2. ADVANCED USAGE
Expand Down
2 changes: 1 addition & 1 deletion Rakefile
Expand Up @@ -19,7 +19,7 @@ begin
gem.email = EMAIL

gem.require_paths = %w{lib}
gem.files = %w(MIT-LICENSE README.textile Rakefile) + Dir.glob(File.join('{generators,tasks}', '**', '*'))
gem.files = %w(MIT-LICENSE README.textile Rakefile init.rb) + Dir.glob(File.join('{generators,rails,tasks}', '**', '*'))
gem.executables = %w()
gem.extra_rdoc_files = %w{README.textile}
end
Expand Down
10 changes: 10 additions & 0 deletions TODO.textile
@@ -0,0 +1,10 @@
h1. TODO

h2. Most probably

* Something like "model_generator_with_factories" (using machinist, factory_girl, ...). Source: http://github.com/vigetlabs/model_generator_with_factories/tree/master
* Break up in different generators: dry_controller, dry_views, etc., and use as dependencies in dry_scaffold

h2. Maybe

* Check for overridden templates in: RAILS_ROOT/lib/dry_scaffold/templates/
2 changes: 1 addition & 1 deletion generators/USAGE
Expand Up @@ -5,4 +5,4 @@ DESCRIPTION
See README.

EXAMPLE
./script/generate dry_scaffold ModelName [attribute:type attribute:type] [--skip-resourceful] [--skip-formtastic] [--skip-views] [--skip-helpers] [--skip-tests]
./script/generate dry_scaffold ModelName [attribute:type attribute:type] [_actions:new,create,...] [_formats:html,json,...] [--skip-resourceful] [--skip-formtastic] [--skip-views] [--skip-helpers] [--skip-tests]
141 changes: 100 additions & 41 deletions generators/dry_scaffold/dry_scaffold_generator.rb
@@ -1,26 +1,59 @@
require 'rubygems'

begin
require 'formtastic'
FORMTASTIC = true
rescue
FORMTASTIC = false
end
begin
require 'inherited_resources'
INHERITED_RESOURCES = true
rescue
INHERITED_RESOURCES = false
end

class DryScaffoldGenerator < Rails::Generator::NamedBase

default_options :resourceful => true,
:formtastic => true,
:skip_tests => false,
:skip_helpers => false,
:skip_views => false,
:include_layout => false

CONTROLLERS_PATH = File.join('app', 'controllers').freeze
HELPERS_PATH = File.join('app', 'helpers').freeze
VIEWS_PATH = File.join('app', 'views').freeze
LAYOUTS_PATH = File.join(VIEWS_PATH, 'layouts').freeze
MODELS_PATH = File.join('app', 'models').freeze
DEFAULT_RESPOND_TO_FORMATS = [:html, :xml, :json].freeze
DEFAULT_MEMBER_ACTIONS = [:show, :new, :edit, :create, :update, :destroy].freeze
DEFAULT_MEMBER_AUTOLOAD_ACTIONS = (DEFAULT_MEMBER_ACTIONS - [:new, :create])
DEFAULT_COLLECTION_ACTIONS = [:index].freeze
DEFAULT_COLLECTION_AUTOLOAD_ACTIONS = DEFAULT_COLLECTION_ACTIONS
DEFAULT_CONTROLLER_ACTIONS = (DEFAULT_COLLECTION_ACTIONS + DEFAULT_MEMBER_ACTIONS)

DEFAULT_VIEW_TEMPLATE_FORMAT = :haml

CONTROLLERS_PATH = File.join('app', 'controllers').freeze
HELPERS_PATH = File.join('app', 'helpers').freeze
VIEWS_PATH = File.join('app', 'views').freeze
LAYOUTS_PATH = File.join(VIEWS_PATH, 'layouts').freeze
MODELS_PATH = File.join('app', 'models').freeze
FUNCTIONAL_TESTS_PATH = File.join('test', 'functional').freeze
UNIT_TESTS_PATH = File.join('test', 'unit', 'helpers').freeze
UNIT_TESTS_PATH = File.join('test', 'unit', 'helpers').freeze

RESOURCEFUL_COLLECTION_NAME = 'collection'.freeze
RESOURCEFUL_SINGULAR_NAME = 'resource'.freeze
RESOURCEFUL_SINGULAR_NAME = 'resource'.freeze

PARTIALS = %w{form item}.freeze
ACTIONS = %w{new edit show index}.freeze
ARG_KEY_VALUE_DIVIDER = ':'.freeze
NON_ATTR_ARG_KEY_PREFIX = '_'.freeze
NON_ATTR_ARG_VALUE_DIVIDER = ','.freeze

# :{action} => [:{partial}, ...]
VIEW_TEMPLATES = {
:index => [:item],
:show => [],
:new => [:form],
:edit => [:form]
}.freeze

default_options :resourceful => INHERITED_RESOURCES,
:formtastic => FORMTASTIC,
:skip_tests => false,
:skip_helpers => false,
:skip_views => false,
:include_layout => false

attr_reader :controller_name,
:controller_class_path,
:controller_file_path,
Expand All @@ -30,7 +63,10 @@ class DryScaffoldGenerator < Rails::Generator::NamedBase
:controller_underscore_name,
:controller_singular_name,
:controller_plural_name,
:collection_name
:collection_name,
:view_template_format,
:actions,
:formats

alias_method :controller_file_name, :controller_underscore_name
alias_method :controller_table_name, :controller_plural_name
Expand All @@ -48,6 +84,25 @@ def initialize(runtime_args, runtime_options = {})
else
@controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
end

@view_template_format = DEFAULT_VIEW_TEMPLATE_FORMAT

@attributes ||= []

# Non-attribute args, i.e. "_actions:new,create". Add to options instead
@args.each do |arg|
arg_entities = arg.split(':')
if arg =~ /^_actions/
@actions = arg_entities[1].split(',').compact.collect { |action| action.to_sym }
elsif arg =~ /^_formats/ || arg =~ /^_respond_to/
@formats = arg_entities[1].split(',').compact.collect { |format| format.to_sym }
else
@attributes << Rails::Generator::GeneratedAttribute.new(*arg_entities)
end
end

@actions ||= DEFAULT_COLLECTION_ACTIONS + DEFAULT_MEMBER_ACTIONS
@formats ||= DEFAULT_RESPOND_TO_FORMATS
end

def manifest
Expand All @@ -60,7 +115,7 @@ def manifest
# Directories.
m.directory File.join(CONTROLLERS_PATH, controller_class_path)
m.directory File.join(HELPERS_PATH, controller_class_path) unless options[:skip_helpers]
m.directory File.join(VIEWS_PATH, controller_class_path, controller_file_name.pluralize) unless options[:skip_views]
m.directory File.join(VIEWS_PATH, controller_class_path, controller_file_name) unless options[:skip_views]
m.directory File.join(FUNCTIONAL_TESTS_PATH, controller_class_path) unless options[:skip_tests]
m.directory File.join(UNIT_TESTS_PATH, controller_class_path) unless options[:skip_tests]

Expand All @@ -71,50 +126,54 @@ def manifest

# Controller Tests.
unless options[:skip_tests]
m.template "controller_test_standard.rb",
m.template 'controller_test_standard.rb',
File.join(FUNCTIONAL_TESTS_PATH, controller_class_path, "#{controller_file_name}_controller_test.rb")
end

# Helpers.
unless options[:skip_helpers]
m.template "helper_standard.rb",
m.template 'helper_standard.rb',
File.join(HELPERS_PATH, controller_class_path, "#{controller_file_name}_helper.rb")
# Helper Tests
unless options[:skip_tests]
m.template "helper_test_standard.rb",
m.template 'helper_test_standard.rb',
File.join(UNIT_TESTS_PATH, controller_class_path, "#{controller_file_name}_helper_test.rb")
end
end

# Views.
unless options[:skip_views]
# View template for each action.
ACTIONS.each do |action|
m.template "view_#{action}.html.haml",
File.join(VIEWS_PATH, controller_file_name, "#{action}.html.haml")
end
# View template for each partial.
PARTIALS.each do |partial|
m.template "view__#{partial}.html.haml",
File.join(VIEWS_PATH, controller_file_name, "_#{partial}.html.haml")
(actions & VIEW_TEMPLATES.keys).each do |action|
m.template "view_#{action}.html.#{view_template_format}", File.join(VIEWS_PATH, controller_file_name, "#{action}.html.#{view_template_format}")
# View template for each partial - if not already copied.
(VIEW_TEMPLATES[action] || []).each do |partial|
m.template "view__#{partial}.html.#{view_template_format}",
File.join(VIEWS_PATH, controller_file_name, "_#{partial}.html.#{view_template_format}")
end
end
end

# Layout.
if options[:include_layout]
m.template "view_layout.html.haml",
File.join(LAYOUTS_PATH, "#{controller_file_name}.html.haml")
m.template "view_layout.html.#{view_template_format}",
File.join(LAYOUTS_PATH, "#{controller_file_name}.html.#{view_template_format}")
end

# Routes.
m.route_resources controller_file_name

# Models - use Rails default generator.
m.dependency 'model', [name] + @args, :collision => :skip
m.dependency 'model', [name] + attributes, :collision => :skip
end
end

protected

def symbol_array_to_expression(array)
":#{array.compact.join(', :')}" if array.present?
end

def assign_names!(name)
super
@collection_name = options[:resourceful] ? RESOURCEFUL_COLLECTION_NAME : @plural_name
Expand Down Expand Up @@ -151,12 +210,6 @@ def add_options!(opt)
opt.on('--include-layout', "Generate layout.") do |v|
options[:include_layout] = v
end

# TODO: How to specify arguments?
opt.on('-r', '--respond-to', "Skip generation of tests.") do |v|
puts v
options[:respond_to] = v
end
end

def model_name
Expand All @@ -165,8 +218,14 @@ def model_name

def banner
"Usage: #{$0} dry_scaffold ModelName [field:type field:type ...]" +
" [--skip-resourceful] [--skip-formtastic]" +
" [--skip-views] [--skip-helpers] [--skip-tests] [--include-layout]"
" [_actions:new,create,...]" +
" [_formats:html,json,...]" +
" [--skip-resourceful]" +
" [--skip-formtastic]" +
" [--skip-views]" +
" [--skip-helpers]" +
" [--skip-tests]" +
" [--include-layout]"
end

end
@@ -1,19 +1,29 @@
class <%= controller_class_name %>Controller < InheritedResources::Base
actions :index, :show, :new, :create, :edit, :update, :destroy
respond_to :html, :xml, :json
<% if actions -%>
actions <%= symbol_array_to_expression(actions) %>
<% end -%>
<% if formats -%>
respond_to <%= symbol_array_to_expression(formats) %>
<% end -%>
<% (actions - DryScaffoldGenerator::DEFAULT_CONTROLLER_ACTIONS).each do |action| -%>
# GET /<%= plural_name %>/<%= action.to_s %>
def <%= action.to_s %>
end
<% end -%>
protected

def collection
paginate_options ||= {}
paginate_options[:page] ||= (params[:page] || 1)
paginate_options[:per_page] ||= (params[:per_page] || 20)
@<%= plural_name %> ||= end_of_association_chain.paginate(paginate_options)
@collection = @<%= plural_name %> ||= end_of_association_chain.paginate(paginate_options)
end
def resource
@<%= singular_name %> ||= end_of_association_chain.find(params[:id])
@resource = @<%= singular_name %> ||= end_of_association_chain.find(params[:id])
end

end

0 comments on commit 570dbaa

Please sign in to comment.