require 'generators/adhoc' require 'rails/generators/migration' require 'rails/generators/generated_attribute' module Adhoc module Generators class PortfolioGenerator < Base include Rails::Generators::Migration no_tasks { attr_accessor :name, :attributes } argument :name, type: :string, default: 'Portfolio', banner: 'PortfolioBanner' class_option :namespace_model, desc: 'If the resource is namespaced, include the model in the namespace.', type: :boolean def initialize(*args, &block) super print_usage unless name.underscore =~ /^[a-z][a-z0-9_\/]+$/ @namespace_model = options.namespace_model? @attributes = [] ['title:string', 'summary:string', 'description:string', 'service_id:integer'].each do |arg| @attributes << Rails::Generators::GeneratedAttribute.new(*arg.split(':')) end end def create_model template 'model.rb', "app/models/#{file_name}.rb" end def create_migration migration_template 'migration.rb', "db/migrate/create_#{plural_name.gsub('/', '_')}.rb" end def create_controller template 'controller.rb', "app/controllers/#{plural_name}_controller.rb" template 'helper.rb', "app/helpers/#{plural_name}_helper.rb" %w[index show new edit].each do |action| template "views/#{action}.html.erb", "app/views/#{plural_name}/#{action}.html.erb" end if form_partial? template "views/_form.html.erb", "app/views/#{plural_name}/_form.html.erb" end namespaces = plural_name.split('/') resource = namespaces.pop route namespaces.reverse.inject("resources :#{resource}") { |acc, namespace| "namespace(:#{namespace}){ #{acc} }" } end private def file_name name.underscore end def constant_name file_name.upcase end def model_name file_name.capitalize end def plural_class_name plural_name.camelize end def plural_name file_name.pluralize end def table_name if name.include?('::') && @namespace_model plural_name.gsub('/', '_') end end def instance_name file_name.gsub('/','_') end def instances_name instance_name.pluralize end def controller_actions %w[index show new edit create update destroy] end def controller_methods(dir_name) controller_actions.map do |action| read_template("#{dir_name}/#{action}.rb") end.join("\n").strip end def read_template(relative_path) ERB.new(File.read(find_in_source_paths(relative_path)), nil, '-').result(binding) end def action?(name) controller_actions.include? name.to_s end def actions?(*names) names.all? { |name| action? name } end def singular_name name.underscore end def item_resource name.underscore.gsub('/','_') end def items_path if action? :index "#{item_resource.pluralize}_path" else "root_path" end end def item_path(options = {}) name = options[:instance_variable] ? "@#{instance_name}" : instance_name suffix = options[:full_url] ? "url" : "path" if options[:action].to_s == "new" "new_#{item_resource}_#{suffix}" elsif options[:action].to_s == "edit" "edit_#{item_resource}_#{suffix}(#{name})" else if name.include?('::') namespace = singular_name.split('/')[0..-2] "[:#{namespace.join(', :')}, #{name}]" else name end end end def item_url if action? :show item_path(:full_url => true, :instance_variable => true) else items_url end end def items_url if action? :index item_resource.pluralize + '_url' else "root_url" end end def form_partial? actions? :new, :edit end def render_form if form_partial? "<%= render \"form\" %>" else read_template("views/_form.html.rb") end end # FIXME: Should be proxied to ActiveRecord::Generators::Base # Implement the required interface for Rails::Generators::Migration. def self.next_migration_number(dirname) #:nodoc: if ActiveRecord::Base.timestamped_migrations Time.now.utc.strftime("%Y%m%d%H%M%S") else "%.3d" % (current_migration_number(dirname) + 1) end end end end end