lib/napa/cli/model.rb
require 'thor'
require 'active_support/all'
require 'napa/cli/generated_attribute'
module Napa
module CLI
class Error < Thor::Error # :nodoc:
end
# Note: This currently does not support namespaced model creation.
class Model < Thor::Group
include Thor::Actions
# Largely modeled off of Rails's:
# - activerecord/lib/rails/generators/active_record/model/model_generator.rb,
# - railties/lib/rails/generators/base.rb, and
# - railties/lib/rails/generators/named_base.rb
argument :name
argument :attributes, type: :array, default: []
class_option :migration, type: :boolean, default: true
class_option :timestamps, type: :boolean, default: true
class_option :indexes, type: :boolean, default: true
class_option :parent, type: :string
def parse_attributes!
self.attributes = (attributes || []).map do |attr|
GeneratedAttribute.parse(attr)
end
end
def generate_model
# In order to check for class collisions, the Grape environment needs to be loaded.
say 'Generating model...'
self.class.source_root "#{File.dirname(__FILE__)}/templates"
create_migration_file
create_model_file
create_factory_file
create_model_spec_file
say 'Done!', :green
end
protected
def version
Time.now.utc.strftime('%Y%m%d%H%M%S')
end
def create_migration_file
return unless options[:migration] && options[:parent].nil?
if options[:indexes] == false
attributes.each { |a| a.attr_options.delete(:index) if a.reference? && !a.has_index? }
end
# This does not currently check for similar migrations.
# This can be done by overriding the CreateFile Thor action and
# implementing the exists? and on_conflict_behavior methods.
template migration_template, "#{migration_output_directory}/#{version}_#{migration_name}.rb"
end
def create_model_file
template model_template, "#{model_output_directory}/#{model_name}.rb"
end
def create_factory_file
template factory_template, "#{factory_output_directory}/#{table_name}.rb"
end
def create_model_spec_file
template model_spec_template, "#{model_spec_output_directory}/#{model_name}_spec.rb"
end
def model_name
name.underscore
end
def migration_name
"create_#{table_name}"
end
def table_name
model_name.pluralize
end
def migration_template
'model/db/migrate/migration.rb.tt'
end
def parent_class_name
options[:parent] || 'ActiveRecord::Base'
end
def migration_output_directory
'./db/migrate'
end
def model_template
'model/app/models/model.rb.tt'
end
def model_output_directory
'./app/models'
end
def factory_template
'model/spec/factories/factory.rb.tt'
end
def factory_output_directory
'./spec/factories'
end
def model_spec_template
'model/spec/models/model_spec.rb.tt'
end
def model_spec_output_directory
'./spec/models'
end
def attributes_with_index
attributes.select { |a| !a.reference? && a.has_index? }
end
end
end
end