require File.dirname(__FILE__) + '/../default_values' # Author: Kristian Mandrup # email: kmandrup@gmail.com require 'generators/rspec_rails3_gen_base' # ================== # TODO: Make hooks for other generators work!!! # see 'hook_for' # ================== module RSpec module Generators class ScaffoldGenerator < NamedBase class_option :default_file_extension, :type => :string, :aliases => "-fe", :default => 'html.erb', :desc => "Default file extension for views" no_tasks do attr_accessor :model_name attr_accessor :model_attributes attr_accessor :controller_actions alias :attributes :model_attributes alias :attributes= :model_attributes= end argument :model_name, :type => :string, :required => true, :banner => 'ModelName' argument :args_for_c_m, :type => :array, :default => [], :banner => 'controller_actions and model:attributes' def initialize(*args, &block) super @my_options ||= {} @controller_actions = [] @model_attributes = [] args_for_c_m.each do |arg| if arg == '!' @my_options[:invert] = true elsif arg.include?(':') @model_attributes << Rails::Generators::GeneratedAttribute.new(*arg.split(':')) else @controller_actions << arg @controller_actions << 'create' if arg == 'new' @controller_actions << 'update' if arg == 'edit' end end @controller_actions.uniq! @model_attributes.uniq! if options.do_invert? || @controller_actions.empty? @controller_actions = all_actions - @controller_actions end if @model_attributes.empty? @my_options[:skip_model] = true # default to skipping model if no attributes passed if model_exists? model_columns_for_attributes.each do |column| @model_attributes << Rails::Generators::GeneratedAttribute.new(column.name.to_s, column.type.to_s) end else @model_attributes << Rails::Generators::GeneratedAttribute.new('name', 'string') end end end def create_files # Controller, helper, views, and spec directories. empty_directory 'spec/controllers' empty_directory 'spec/routing' empty_directory 'spec/models' empty_directory 'spec/helpers' empty_directory 'spec/fixtures' empty_directory 'spec/views' empty_directory 'spec/integration' # Controller spec, class, and helper. template 'routing_spec.rb', File.join('spec/routing', controller_class_path, "#{controller_file_name}_routing_spec.rb") template 'controller_spec.rb', File.join('spec/controllers', controller_class_path, "#{controller_file_name}_controller_spec.rb") template 'helper_spec.rb', File.join('spec/helpers', class_path, "#{controller_file_name}_helper_spec.rb") # View specs template "edit_erb_spec.rb", File.join('spec/views', controller_class_path, controller_file_name, "edit.#{default_file_extension}_spec.rb") template "index_erb_spec.rb", File.join('spec/views', controller_class_path, controller_file_name, "index.#{default_file_extension}_spec.rb") template "new_erb_spec.rb", File.join('spec/views', controller_class_path, controller_file_name, "new.#{default_file_extension}_spec.rb") template "show_erb_spec.rb", File.join('spec/views', controller_class_path, controller_file_name, "show.#{default_file_extension}_spec.rb") # route_resources controller_file_name end # tries to find generator within rspec first, then in rails # use :in, fx :in => :rails to be more specific! # TODO: Make hooks work!!! # hook_for :integration_spec, :model, :migration, :scaffold, :layout no_tasks do def default_file_extension options[:default_file_extension] end def controller_class_name "#{class_name}Controller" end def controller_class_path class_path || "controller/#{name}" end def controller_file_name name end def model_exists? File.exist? destination_path("app/models/#{singular_name}.rb") end def destination_path(path) File.join(destination_root, path) end def scaffold_views %w[ index show new edit ] end def actions @controller_actions end def all_actions %w[index show new create edit update destroy] end def action?(name) controller_actions.include? name.to_s end def actions?(*names) names.all? { |name| action? name } end def singular_name model_name.underscore end def plural_name model_name.underscore.pluralize end def class_name model_name.camelize end def plural_class_name plural_name.camelize end end end end end # What is this for??? module Rails module Generators class GeneratedAttribute def input_type @input_type ||= map_to_input_type end protected def map_to_input_type case type when :text "textarea" else "input" end end end end end