diff --git a/README.md b/README.md index b12d80f..5367580 100644 --- a/README.md +++ b/README.md @@ -730,6 +730,17 @@ gem 'aasm' % sudo gem install pkg/aasm-x.y.z.gem ``` +### Generators + +After installing Aasm you can run generator: + +```sh +% rails generate aasm NAME [COLUMN_NAME] +``` +Replace NAME with the Model name, COLUMN_NAME is optional(default is 'aasm_state'). +This will create a model (if one does not exist) and configure it with aasm block. +For Active record orm a migration file is added to add aasm state column to table. + ## Latest changes ## Take a look at the [CHANGELOG](https://github.com/aasm/aasm/blob/master/CHANGELOG.md) for details about recent changes to the current version. diff --git a/aasm.gemspec b/aasm.gemspec index 5d0ab8d..8dcb14f 100644 --- a/aasm.gemspec +++ b/aasm.gemspec @@ -19,6 +19,7 @@ Gem::Specification.new do |s| s.add_development_dependency 'rake' s.add_development_dependency 'sdoc' s.add_development_dependency 'rspec', ">= 3" + s.add_development_dependency 'generator_spec' # debugging # s.add_development_dependency 'debugger' diff --git a/lib/generators/aasm/aasm_generator.rb b/lib/generators/aasm/aasm_generator.rb new file mode 100644 index 0000000..2f95c94 --- /dev/null +++ b/lib/generators/aasm/aasm_generator.rb @@ -0,0 +1,17 @@ +require 'rails/generators/named_base' + +module AASM + module Generators + class AASMGenerator < Rails::Generators::NamedBase + + source_root File.expand_path("../templates", __FILE__) + argument :column_name, type: :string, default: 'aasm_state' + + desc "Generates a model with the given NAME (if one does not exist) with aasm " << + "block and migration to add aasm_state column." + + hook_for :orm + + end + end +end diff --git a/lib/generators/aasm/orm_helpers.rb b/lib/generators/aasm/orm_helpers.rb new file mode 100644 index 0000000..8234927 --- /dev/null +++ b/lib/generators/aasm/orm_helpers.rb @@ -0,0 +1,35 @@ +module AASM + module Generators + module OrmHelpers + + def model_contents + if column_name == 'aasm_state' +< '#{column_name}' do + end +RUBY + end + end + + private + + def model_exists? + File.exists?(File.join(destination_root, model_path)) + end + + def model_path + @model_path ||= File.join("app", "models", "#{file_path}.rb") + end + + end + end +end diff --git a/lib/generators/active_record/aasm_generator.rb b/lib/generators/active_record/aasm_generator.rb new file mode 100644 index 0000000..e8746a1 --- /dev/null +++ b/lib/generators/active_record/aasm_generator.rb @@ -0,0 +1,38 @@ +require 'rails/generators/active_record' +require 'generators/aasm/orm_helpers' + +module ActiveRecord + module Generators + class AASMGenerator < ActiveRecord::Generators::Base + include AASM::Generators::OrmHelpers + + argument :column_name, type: :string, default: 'aasm_state' + + source_root File.expand_path("../templates", __FILE__) + + def copy_aasm_migration + if model_exists? + migration_template "migration_existing.rb", "db/migrate/add_aasm_state_to_#{table_name}.rb" + else + migration_template "migration.rb", "db/migrate/aasm_create_#{table_name}.rb" + end + end + + def generate_model + invoke "active_record:model", [name], migration: false unless model_exists? + end + + def inject_aasm_content + content = model_contents + + class_path = if namespaced? + class_name.to_s.split("::") + else + [class_name] + end + inject_into_class(model_path, class_path.last, content) if model_exists? + end + + end + end +end diff --git a/lib/generators/active_record/templates/migration.rb b/lib/generators/active_record/templates/migration.rb new file mode 100644 index 0000000..e5e706f --- /dev/null +++ b/lib/generators/active_record/templates/migration.rb @@ -0,0 +1,8 @@ +class AASMCreate<%= table_name.camelize %> < ActiveRecord::Migration + def change + create_table(:<%= table_name %>) do |t| + t.string :<%= column_name %> + t.timestamps null: false + end + end +end diff --git a/lib/generators/active_record/templates/migration_existing.rb b/lib/generators/active_record/templates/migration_existing.rb new file mode 100644 index 0000000..764bf71 --- /dev/null +++ b/lib/generators/active_record/templates/migration_existing.rb @@ -0,0 +1,9 @@ +class AddAASMTo<%= table_name.camelize %> < ActiveRecord::Migration + def self.up + add_column :<%= table_name %>, :<%= column_name %>, :string + end + + def self.down + remove_column :<%= table_name %>, :<%= column_name %> + end +end diff --git a/lib/generators/mongoid/aasm_generator.rb b/lib/generators/mongoid/aasm_generator.rb new file mode 100644 index 0000000..cc57904 --- /dev/null +++ b/lib/generators/mongoid/aasm_generator.rb @@ -0,0 +1,28 @@ +require 'rails/generators/named_base' +require 'generators/aasm/orm_helpers' + +module Mongoid + module Generators + class AASMGenerator < Rails::Generators::NamedBase + include AASM::Generators::OrmHelpers + + argument :column_name, type: :string, default: 'aasm_state' + + def generate_model + invoke "mongoid:model", [name] unless model_exists? + end + + def inject_aasm_content + inject_into_file model_path, model_contents, after: "include Mongoid::Document\n" if model_exists? + end + + def inject_field_types + inject_into_file model_path, migration_data, after: "include Mongoid::Document\n" if model_exists? + end + + def migration_data + " field :#{column_name}" + end + end + end +end diff --git a/spec/generators/active_record_generator_spec.rb b/spec/generators/active_record_generator_spec.rb new file mode 100644 index 0000000..d455727 --- /dev/null +++ b/spec/generators/active_record_generator_spec.rb @@ -0,0 +1,39 @@ +require 'spec_helper' +require 'generator_spec' +require 'generators/active_record/aasm_generator' + +describe ActiveRecord::Generators::AASMGenerator, type: :generator do + destination File.expand_path("../../../tmp", __FILE__) + + before(:all) do + prepare_destination + end + + it "creates model with aasm block for default column_name" do + run_generator %w(user) + assert_file "app/models/user.rb", /include AASM\n\n aasm do\n end\n/ + end + + it "creates model with aasm block for custom column_name" do + run_generator %w(user state) + assert_file "app/models/user.rb", /aasm :column => 'state' do\n end\n/ + end + + it "creates model with aasm block for namespaced model" do + run_generator %w(Admin::User state) + assert_file "app/models/admin/user.rb", /aasm :column => 'state' do\n end\n/ + end + + it "creates migration for model with aasm_column" do + run_generator %w(post) + assert_migration "db/migrate/aasm_create_posts.rb", /create_table(:posts) do |t|\n t.string :aasm_state\n/ + end + + it "add aasm_column in existing model" do + run_generator %w(job) + assert_file "app/models/job.rb" + run_generator %w(job) + assert_migration "db/migrate/add_aasm_state_to_jobs.rb" + end + +end diff --git a/spec/generators/mongoid_generator_spec.rb b/spec/generators/mongoid_generator_spec.rb new file mode 100644 index 0000000..1f5866f --- /dev/null +++ b/spec/generators/mongoid_generator_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' +require 'generator_spec' +require 'generators/mongoid/aasm_generator' + +begin + require "mongoid" + + describe Mongoid::Generators::AASMGenerator, type: :generator do + destination File.expand_path("../../../tmp", __FILE__) + + before(:all) do + prepare_destination + end + + it "creates model with aasm block for default column_name" do + run_generator %w(user) + assert_file "app/models/user.rb", /include AASM\n\n aasm do\n end\n/ + end + + it "creates model with aasm block for custom column_name" do + run_generator %w(user state) + assert_file "app/models/user.rb", /aasm :column => 'state' do\n end\n/ + end + + it "creates model with aasm block for namespaced model" do + run_generator %w(Admin::User state) + assert_file "app/models/admin/user.rb", /aasm :column => 'state' do\n end\n/ + end + + end +rescue LoadError + puts "Not running Mongoid specs because mongoid gem is not installed!!!" +end