mack-active_record 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/README +3 -0
  2. data/lib/helpers/orm_helpers.rb +77 -0
  3. data/lib/mack-active_record.rb +23 -0
  4. data/lib/mack-active_record_tasks.rb +3 -0
  5. data/lib/migration_generator/migration_generator.rb +41 -0
  6. data/lib/migration_generator/templates/db/migrations/%=@migration_name%.rb.template +31 -0
  7. data/lib/model_generator/manifest.yml +11 -0
  8. data/lib/model_generator/model_generator.rb +46 -0
  9. data/lib/model_generator/templates/model.rb.template +3 -0
  10. data/lib/model_generator/templates/test.rb.template +9 -0
  11. data/lib/scaffold_generator/manifest.yml +24 -0
  12. data/lib/scaffold_generator/scaffold_generator.rb +41 -0
  13. data/lib/scaffold_generator/templates/app/controllers/controller.rb.template +50 -0
  14. data/lib/scaffold_generator/templates/app/views/edit.html.erb.template +19 -0
  15. data/lib/scaffold_generator/templates/app/views/index.html.erb.template +41 -0
  16. data/lib/scaffold_generator/templates/app/views/new.html.erb.template +19 -0
  17. data/lib/scaffold_generator/templates/app/views/show.html.erb.template +12 -0
  18. data/lib/scaffold_generator/templates/test.rb.template +9 -0
  19. data/lib/tasks/db_create_drop_tasks.rake +70 -0
  20. data/lib/tasks/db_migration_tasks.rake +86 -0
  21. data/test/database.yml +3 -0
  22. data/test/fixtures/add_users_migration.rb.fixture +9 -0
  23. data/test/fixtures/album.rb.fixture +3 -0
  24. data/test/fixtures/album_unit_test.rb.fixture +9 -0
  25. data/test/fixtures/create_users_migration.rb.fixture +12 -0
  26. data/test/fixtures/routes.rb.fixture +3 -0
  27. data/test/fixtures/zoo.rb.fixture +3 -0
  28. data/test/fixtures/zoo_no_cols/edit.html.erb.fixture +11 -0
  29. data/test/fixtures/zoo_no_cols/index.html.erb.fixture +20 -0
  30. data/test/fixtures/zoo_no_cols/new.html.erb.fixture +11 -0
  31. data/test/fixtures/zoo_no_cols/show.html.erb.fixture +6 -0
  32. data/test/fixtures/zoo_with_cols/edit.html.erb.fixture +19 -0
  33. data/test/fixtures/zoo_with_cols/index.html.erb.fixture +26 -0
  34. data/test/fixtures/zoo_with_cols/new.html.erb.fixture +19 -0
  35. data/test/fixtures/zoo_with_cols/show.html.erb.fixture +22 -0
  36. data/test/fixtures/zoo_with_cols/zoos_controller.rb.fixture +50 -0
  37. data/test/generators/migration_generator_test.rb +71 -0
  38. data/test/generators/model_generator_test.rb +37 -0
  39. data/test/generators/scaffold_generator_test.rb +61 -0
  40. data/test/lib/user.rb +3 -0
  41. data/test/tasks/db_migration_tasks_test.rb +57 -0
  42. data/test/test_helper.rb +77 -0
  43. metadata +116 -0
data/README ADDED
@@ -0,0 +1,3 @@
1
+ README
2
+ ========================================================================
3
+ mack-active_record was developed by: markbates
@@ -0,0 +1,77 @@
1
+ class ActiveRecord::Base # :nodoc:
2
+ def business_display_name
3
+ self.class.name#.titlecase
4
+ end
5
+ end
6
+
7
+ module Mack
8
+ module ViewHelpers
9
+ module OrmHelpers
10
+ DEFAULT_PARTIAL = %{
11
+ <div>
12
+ <div class="errorExplanation" id="errorExplanation">
13
+ <h2><%= pluralize_word(errors.size, "error") %> occured.</h2>
14
+ <ul>
15
+ <% for error in errors %>
16
+ <li><%= error %></li>
17
+ <% end %>
18
+ </ul>
19
+ </div>
20
+ </div>
21
+ }
22
+
23
+ def error_messages_for(object_names = [], view_partial = nil)
24
+ object_names = [object_names]
25
+ object_names.flatten!
26
+ app_errors = []
27
+ object_names.each do |name|
28
+ object = instance_variable_get("@#{name}")
29
+ if object
30
+ object.errors.each do |key, value|
31
+ key = key.to_s
32
+ if value.is_a?(Array)
33
+ value.each do |v|
34
+ if v.match(/^\^/)
35
+ app_errors << v[1..v.length]
36
+ else
37
+ if key.class == String and key == "base"
38
+ app_errors << "#{v}"
39
+ else
40
+ app_errors << "#{object.business_display_name} #{key.underscore.split('_').join(' ')} #{v}"
41
+ end
42
+ end
43
+ end
44
+ else
45
+ if value.match(/^\^/)
46
+ app_errors << value[1..value.length]
47
+ else
48
+ if key.class == String and key == "base"
49
+ app_errors << "#{value}"
50
+ else
51
+ app_errors << "#{object.business_display_name} #{key.underscore.split('_').join(' ')} #{value}"
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ File.join(Mack::Configuration.views_directory, "application", "_error_messages.html.erb")
59
+ unless app_errors.empty?
60
+ if view_partial.nil?
61
+ if File.exist?(File.join(Mack::Configuration.views_directory, "application", "_error_messages.html.erb"))
62
+ render :partial => "application/error_messages", :locals => {:errors => app_errors}
63
+ else
64
+ render :text => DEFAULT_PARTIAL, :locals => {:errors => app_errors}
65
+ end
66
+ else
67
+ render :partial => view_partial, :locals => {:errors => app_errors}
68
+ end
69
+ else
70
+ ""
71
+ end
72
+ end
73
+
74
+ # self.include_safely_into(Mack::ViewBinder)
75
+ end # OrmHelpers
76
+ end # ViewHelpers
77
+ end # Mack
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ require 'genosaurus'
3
+ require 'erubis'
4
+ begin
5
+ require 'mack-orm_common'
6
+ rescue Exception => e
7
+ puts e
8
+ end
9
+
10
+ require 'activerecord'
11
+
12
+ dbs = Mack::Configuration.database_configurations
13
+
14
+ unless dbs.nil?
15
+ ActiveRecord::Base.establish_connection(dbs[Mack::Configuration.env])
16
+ class SchemaInfo < ActiveRecord::Base # :nodoc:
17
+ set_table_name 'schema_info'
18
+ end
19
+ end
20
+ [:helpers, :migration_generator, :model_generator, :scaffold_generator].each do |folder|
21
+ Dir.glob(File.join(File.dirname(__FILE__), folder.to_s, "**/*.rb")).each {|f| require f}
22
+ end
23
+ # Dir.glob(File.join(File.dirname(__FILE__), "tasks", "**/*.rake")).each {|f| load f}
@@ -0,0 +1,3 @@
1
+ Dir.glob(File.join(File.dirname(__FILE__), "tasks", "*.rake")).each do |f|
2
+ load(f)
3
+ end
@@ -0,0 +1,41 @@
1
+ # This will generate a migration for your application.
2
+ #
3
+ # Example without columns:
4
+ # rake generate:migration name=create_users
5
+ #
6
+ # db/migrations/<number>_create_users.rb:
7
+ # class CreateUsers < ActiveRecord::Migration
8
+ # self.up
9
+ # end
10
+ #
11
+ # self.down
12
+ # end
13
+ # end
14
+ #
15
+ # Example with columns:
16
+ # rake generate:migration name=create_users cols=username:string,email_address:string,created_at:datetime,updated_at:datetime
17
+ #
18
+ # db/migrations/<number>_create_users.rb:
19
+ # class CreateUsers < ActiveRecord::Migration
20
+ # self.up
21
+ # create_table :users do |t|
22
+ # t.column :username, :string
23
+ # t.column :email_address, :string
24
+ # t.column :created_at, :datetime
25
+ # t.column :updated_at, :datetime
26
+ # end
27
+ #
28
+ # self.down
29
+ # drop_table :users
30
+ # end
31
+ # end
32
+ class MigrationGenerator < Genosaurus
33
+
34
+ require_param :name
35
+
36
+ def setup
37
+ @table_name = param(:name).underscore.plural.gsub("create_", "")
38
+ @migration_name = "#{next_migration_number}_#{param(:name).underscore}"
39
+ end
40
+
41
+ end
@@ -0,0 +1,31 @@
1
+ class <%= param(:name).camelcase %> < ActiveRecord::Migration
2
+
3
+ def self.up
4
+ <%
5
+ unless columns.empty?
6
+ -%>
7
+ create_table :<%= @table_name %> do |t|
8
+ <%
9
+ for column in columns
10
+ -%>
11
+ t.column :<%= column.column_name %>, :<%= column.column_type %>
12
+ <%
13
+ end
14
+ -%>
15
+ end
16
+ <%
17
+ end
18
+ -%>
19
+ end
20
+
21
+ def self.down
22
+ <%
23
+ unless columns.empty?
24
+ -%>
25
+ drop_table :<%= @table_name %>
26
+ <%
27
+ end
28
+ -%>
29
+ end
30
+
31
+ end
@@ -0,0 +1,11 @@
1
+ models_directory:
2
+ type: directory
3
+ output_path: <%= File.join("app", "models") %>
4
+ model_template:
5
+ type: file
6
+ template_path: <%= File.join(templates_directory_path, "model.rb.template") %>
7
+ output_path: <%= File.join("app", "models", "#{param(:name).singular.underscore}.rb") %>
8
+ test_template:
9
+ type: file
10
+ template_path: <%= File.join(templates_directory_path, "test.rb.template") %>
11
+ output_path: <%= File.join("test", "unit", "#{param(:name).singular.underscore}_test.rb") %>
@@ -0,0 +1,46 @@
1
+ # This will generate an ORM 'model' for your application based on the specified ORM you're using.
2
+ #
3
+ # Example without columns:
4
+ # rake generate:model name=user
5
+ #
6
+ # app/models/user.rb:
7
+ # class User < ActiveRecord::Base
8
+ # end
9
+ # db/migrations/<number>_create_users.rb:
10
+ # class CreateUsers < ActiveRecord::Migration
11
+ # self.up
12
+ # end
13
+ #
14
+ # self.down
15
+ # end
16
+ # end
17
+ #
18
+ # Example with columns:
19
+ # rake generate:model name=user cols=username:string,email_address:string,created_at:datetime,updated_at:datetime
20
+ #
21
+ # app/models/user.rb:
22
+ # class User < ActiveRecord::Base
23
+ # end
24
+ # db/migrations/<number>_create_users.rb:
25
+ # class CreateUsers < ActiveRecord::Migration
26
+ # self.up
27
+ # create_table :users do |t|
28
+ # t.column :username, :string
29
+ # t.column :email_address, :string
30
+ # t.column :created_at, :datetime
31
+ # t.column :updated_at, :datetime
32
+ # end
33
+ #
34
+ # self.down
35
+ # drop_table :users
36
+ # end
37
+ # end
38
+ class ModelGenerator < Genosaurus
39
+
40
+ require_param :name
41
+
42
+ def after_generate
43
+ MigrationGenerator.run(@options.merge({"name" => "create_#{param(:name).plural}"}))
44
+ end
45
+
46
+ end
@@ -0,0 +1,3 @@
1
+ class <%= param(:name).singular.camelcase %> < ActiveRecord::Base
2
+
3
+ end
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + '/../test_helper.rb'
2
+
3
+ class <%= param(:name).singular.camelcase %>Test < Test::Unit::TestCase
4
+
5
+ def test_truth
6
+ assert true
7
+ end
8
+
9
+ end
@@ -0,0 +1,24 @@
1
+ controller_template:
2
+ type: file
3
+ template_path: <%= File.join(templates_directory_path, "app", "controllers", "controller.rb.template") %>
4
+ output_path: <%= File.join("app", "controllers", "#{@name_plural}_controller.rb") %>
5
+ edit_template:
6
+ type: file
7
+ template_path: <%= File.join(templates_directory_path, "app", "views", "edit.html.erb.template") %>
8
+ output_path: <%= File.join("app", "views", @name_plural, "edit.html.erb") %>
9
+ index_template:
10
+ type: file
11
+ template_path: <%= File.join(templates_directory_path, "app", "views", "index.html.erb.template") %>
12
+ output_path: <%= File.join("app", "views", @name_plural, "index.html.erb") %>
13
+ new_template:
14
+ type: file
15
+ template_path: <%= File.join(templates_directory_path, "app", "views", "new.html.erb.template") %>
16
+ output_path: <%= File.join("app", "views", @name_plural, "new.html.erb") %>
17
+ show_template:
18
+ type: file
19
+ template_path: <%= File.join(templates_directory_path, "app", "views", "show.html.erb.template") %>
20
+ output_path: <%= File.join("app", "views", @name_plural, "show.html.erb") %>
21
+ functional_teat_template:
22
+ type: file
23
+ template_path: <%= File.join(templates_directory_path, "test.rb.template") %>
24
+ output_path: <%= File.join("test", "functional", "#{@name_plural}_controller_test.rb") %>
@@ -0,0 +1,41 @@
1
+ # Generates scaffold for Mack applications.
2
+ #
3
+ # Example:
4
+ # rake generate:scaffold name=post
5
+ class ScaffoldGenerator < Genosaurus
6
+
7
+ require_param :name
8
+
9
+ def setup
10
+ @name_singular = param(:name).singular.underscore
11
+ @name_plural = param(:name).plural.underscore
12
+ @name_singular_camel = @name_singular.camelcase
13
+ @name_plural_camel = @name_plural.camelcase
14
+ end
15
+
16
+ def after_generate
17
+ ModelGenerator.run(@options)
18
+ update_routes_file
19
+ end
20
+
21
+ def update_routes_file
22
+ # update routes.rb
23
+ routes = File.join(Mack::Configuration.config_directory, "routes.rb")
24
+ rf = File.open(routes).read
25
+ unless rf.match(".resource :#{@name_plural}")
26
+ puts "Updating routes.rb"
27
+ nrf = ""
28
+ rf.each do |line|
29
+ if line.match("Mack::Routes.build")
30
+ x = line.match(/\|(.+)\|/).captures
31
+ line << "\n #{x}.resource :#{@name_plural} # Added by rake generate:scaffold name=#{param(:name)}\n"
32
+ end
33
+ nrf << line
34
+ end
35
+ File.open(routes, "w") do |f|
36
+ f.puts nrf
37
+ end
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,50 @@
1
+ class <%= @name_plural_camel %>Controller < Mack::Controller::Base
2
+
3
+ # GET /<%= @name_plural %>
4
+ def index
5
+ @<%= @name_plural %> = <%= @name_singular_camel %>.find(:all)
6
+ end
7
+
8
+ # GET /<%= @name_plural %>/1
9
+ def show
10
+ @<%= @name_singular %> = <%= @name_singular_camel %>.find(params(:id))
11
+ end
12
+
13
+ # GET /<%= @name_plural %>/new
14
+ def new
15
+ @<%= @name_singular %> = <%= @name_singular_camel %>.new
16
+ end
17
+
18
+ # GET /<%= @name_plural %>/1/edit
19
+ def edit
20
+ @<%= @name_singular %> = <%= @name_singular_camel %>.find(params(:id))
21
+ end
22
+
23
+ # POST /<%= @name_plural %>
24
+ def create
25
+ @<%= @name_singular %> = <%= @name_singular_camel %>.new(params(:<%= @name_singular %>))
26
+ if @<%= @name_singular %>.save
27
+ redirect_to(<%= @name_plural %>_show_url(:id => @<%= @name_singular %>.id))
28
+ else
29
+ render(:action => "new")
30
+ end
31
+ end
32
+
33
+ # PUT /<%= @name_plural %>/1
34
+ def update
35
+ @<%= @name_singular %> = <%= @name_singular_camel %>.find(params(:id))
36
+ if @<%= @name_singular %>.update_attributes(params(:<%= @name_singular %>))
37
+ redirect_to(<%= @name_plural %>_show_url(:id => @<%= @name_singular %>.id))
38
+ else
39
+ render(:action => "edit")
40
+ end
41
+ end
42
+
43
+ # DELETE /<%= @name_plural %>/1
44
+ def delete
45
+ @<%= @name_singular %> = <%= @name_singular_camel %>.find(params(:id))
46
+ @<%= @name_singular %>.destroy
47
+ redirect_to(<%= @name_plural %>_index_url)
48
+ end
49
+
50
+ end
@@ -0,0 +1,19 @@
1
+ <h1>Edit <%= @name_singular_camel %></h1>
2
+
3
+ <%%= error_messages_for :<%= @name_singular %> %>
4
+
5
+ <%% form(<%= @name_singular %>s_update_url(:id => @<%= @name_singular %>.id), :class => "edit_<%= @name_singular %>", :id => "edit_<%= @name_singular %>", :method => :put) do %>
6
+ <% for column in columns -%>
7
+ <% unless column.column_name == "created_at" || column.column_name == "updated_at" -%>
8
+ <p>
9
+ <b><%= column.column_name.singular.camelcase %></b><br />
10
+ <%= column.form_field %>
11
+ </p>
12
+ <% end -%>
13
+ <% end -%>
14
+ <p>
15
+ <input id="<%= @name_singular %>_submit" name="commit" type="submit" value="Update" />
16
+ </p>
17
+ <%% end %>
18
+
19
+ <%%= link_to("Back", <%= @name_singular %>s_index_url) %>
@@ -0,0 +1,41 @@
1
+ <h1>Listing <%= @name_plural_camel %></h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <%
6
+ unless columns.empty?
7
+ columns.each do |col|
8
+ -%>
9
+ <th><%= col.column_name.camelcase %></th>
10
+ <%
11
+ end
12
+ else
13
+ -%>
14
+ <th>&nbsp;</th>
15
+ <%
16
+ end
17
+ -%>
18
+ </tr>
19
+
20
+ <%% for <%= @name_singular %> in @<%= @name_plural %> %>
21
+ <tr>
22
+ <%
23
+ unless columns.empty?
24
+ columns.each do |col| -%>
25
+ <td><%%= <%= @name_singular %>.<%= col.column_name %> %></td>
26
+ <%
27
+ end
28
+ else
29
+ -%>
30
+ <td>&nbsp;</td>
31
+ <% end -%>
32
+ <td><%%= link_to("Show", <%= @name_plural %>_show_url(:id => <%= @name_singular %>.id)) %></td>
33
+ <td><%%= link_to("Edit", <%= @name_plural %>_edit_url(:id => <%= @name_singular %>.id)) %></td>
34
+ <td><%%= link_to("Delete", <%= @name_plural %>_delete_url(:id => <%= @name_singular %>.id), :method => :delete, :confirm => "Are you sure?") %></td>
35
+ </tr>
36
+ <%% end %>
37
+ </table>
38
+
39
+ <br />
40
+
41
+ <%%= link_to("New <%= @name_singular_camel %>", <%= @name_plural %>_new_url) %>
@@ -0,0 +1,19 @@
1
+ <h1>New <%= @name_singular_camel %></h1>
2
+
3
+ <%%= error_messages_for :<%= @name_singular %> %>
4
+
5
+ <%% form(<%= @name_singular %>s_create_url, :class => "new_<%= @name_singular %>", :id => "new_<%= @name_singular %>") do %>
6
+ <% for column in columns -%>
7
+ <% unless column.column_name == "created_at" || column.column_name == "updated_at" -%>
8
+ <p>
9
+ <b><%= column.column_name.singular.camelcase %></b><br />
10
+ <%= column.form_field %>
11
+ </p>
12
+ <% end -%>
13
+ <% end -%>
14
+ <p>
15
+ <input id="<%= @name_singular %>_submit" name="commit" type="submit" value="Create" />
16
+ </p>
17
+ <%% end %>
18
+
19
+ <%%= link_to("Back", <%= @name_singular %>s_index_url) %>
@@ -0,0 +1,12 @@
1
+ <p>
2
+ <h1><%= @name_singular_camel %></h1>
3
+ </p>
4
+ <% for column in columns -%>
5
+ <p>
6
+ <b><%= column.column_name.singular.camelcase %></b><br />
7
+ <%%= @<%= @name_singular %>.<%= column.column_name %> %>
8
+ </p>
9
+ <% end -%>
10
+
11
+ <%%= link_to("Edit", <%= @name_plural %>_edit_url(:id => @<%= @name_singular %>.id)) %> |
12
+ <%%= link_to("Back", <%= @name_plural %>_index_url) %>
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + '/../test_helper.rb'
2
+
3
+ class <%= @name_plural_camel %>ControllerTest < Test::Unit::TestCase
4
+
5
+ def test_truth
6
+ assert true
7
+ end
8
+
9
+ end
@@ -0,0 +1,70 @@
1
+ require 'rake'
2
+ namespace :db do
3
+
4
+ desc "Create the database for your environment."
5
+ task :create => :environment do
6
+ drop_create_database
7
+ end
8
+
9
+ namespace :create do
10
+
11
+ desc "Creates your Full environment. Does NOT create your production database!"
12
+ task :all => :environment do
13
+ drop_create_database("development")
14
+ drop_create_database("test")
15
+ ActiveRecord::Base.establish_connection(Mack::Configuration.database_configurations["development"])
16
+ Rake::Task["db:migrate"].invoke
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+
23
+ private
24
+ def drop_create_database(env = Mack::Configuration.env)
25
+ abcs = Mack::Configuration.database_configurations
26
+ db_settings = abcs[env]
27
+ case db_settings["adapter"]
28
+ when "mysql"
29
+ ActiveRecord::Base.establish_connection(
30
+ :adapter => "mysql",
31
+ :host => "localhost",
32
+ :database => "mysql",
33
+ :username => ENV["DB_USERNAME"] || "root",
34
+ :password => ENV["DB_PASSWORD"] || ""
35
+ )
36
+ puts "Dropping (MySQL): #{db_settings["database"]}"
37
+ ActiveRecord::Base.connection.execute "DROP DATABASE IF EXISTS `#{db_settings["database"]}`"
38
+
39
+ if db_settings["collation"]
40
+ puts "Dropping (MySQL): #{db_settings["database"]}"
41
+ ActiveRecord::Base.connection.execute "CREATE DATABASE `#{db_settings["database"]}` DEFAULT CHARACTER SET `#{db_settings["charset"] || 'utf8'}` COLLATE `#{db_settings["collation"]}`"
42
+ else
43
+ puts "Creating (MySQL): #{db_settings["database"]}"
44
+ ActiveRecord::Base.connection.execute "CREATE DATABASE `#{db_settings["database"]}` DEFAULT CHARACTER SET `#{db_settings["charset"] || 'utf8'}`"
45
+ end
46
+ when "postgresql"
47
+ ENV['PGHOST'] = db_settings["host"] if db_settings["host"]
48
+ ENV['PGPORT'] = db_settings["port"].to_s if db_settings["port"]
49
+ ENV['PGPASSWORD'] = db_settings["password"].to_s if db_settings["password"]
50
+ enc_option = "-E #{db_settings["encoding"]}" if db_settings["encoding"]
51
+
52
+ ActiveRecord::Base.clear_active_connections!
53
+ begin
54
+ puts "Dropping (PostgreSQL): #{db_settings["database"]}"
55
+ `dropdb -U "#{db_settings["username"]}" #{db_settings["database"]}`
56
+ rescue Exception => e
57
+ end
58
+
59
+ begin
60
+ puts "Creating (PostgreSQL): #{db_settings["database"]}"
61
+ `createdb #{enc_option} -U "#{db_settings["username"]}" #{db_settings["database"]}`
62
+ rescue Exception => e
63
+ end
64
+ when 'sqlite3'
65
+ ActiveRecord::Base.clear_active_connections!
66
+ FileUtils.rm_rf(db_settings["database"])
67
+ else
68
+ raise "Task not supported by '#{db_settings["adapter"]}'"
69
+ end
70
+ end
@@ -0,0 +1,86 @@
1
+ require 'rake'
2
+ namespace :db do
3
+
4
+ desc "Migrate the database through scripts in db/migrations"
5
+ task :migrate => "db:schema:create" do
6
+ migration_files.each do |migration|
7
+ require migration
8
+ migration = File.basename(migration, ".rb")
9
+ m_number = migration_number(migration)
10
+ if m_number > @schema_info.version
11
+ migration_name(migration).camelcase.constantize.up
12
+ @schema_info.version += 1
13
+ @schema_info.save
14
+ end
15
+ end # each
16
+ end # migrate
17
+
18
+ desc "Rolls the schema back to the previous version. Specify the number of steps with STEP=n"
19
+ task :rollback => ["db:schema:create", "db:abort_if_pending_migrations"] do
20
+ migrations = migration_files.reverse
21
+ (ENV["STEP"] || 1).to_i.times do |step|
22
+ migration = migrations[step]
23
+ require migration
24
+ migration = File.basename(migration, ".rb")
25
+ m_number = migration_number(migration)
26
+ if m_number == @schema_info.version
27
+ migration_name(migration).camelcase.constantize.down
28
+ @schema_info.version -= 1
29
+ @schema_info.save
30
+ end
31
+ end
32
+
33
+ end # rollback
34
+
35
+ desc "Raises an error if there are pending migrations"
36
+ task :abort_if_pending_migrations do
37
+ migrations = migration_files.reverse
38
+ return if migrations.empty?
39
+ migration = migrations.first
40
+ migration = File.basename(migration, ".rb")
41
+ m_number = migration_number(migration)
42
+ if m_number > @schema_info.version
43
+ raise Mack::Errors::UnrunMigrations.new(m_number - @schema_info.version)
44
+ end
45
+ end
46
+
47
+ desc "Displays the current schema version of your database"
48
+ task :version => "db:schema:create" do
49
+ puts "\nYour database is currently at version: #{@schema_info.version}\n"
50
+ end
51
+
52
+ private
53
+ namespace :schema do
54
+
55
+ task :create => "mack:environment" do
56
+ require 'active_record/migration'
57
+ class CreateSchemaInfo < ActiveRecord::Migration # :nodoc:
58
+ def self.up
59
+ create_table :schema_info do |t|
60
+ t.column :version, :integer, :default => 0
61
+ end
62
+ end # up
63
+ end # CreateSchemaInfo
64
+ unless SchemaInfo.table_exists?
65
+ CreateSchemaInfo.up
66
+ SchemaInfo.create(:version => 0)
67
+ end
68
+ @schema_info = SchemaInfo.find(:first)
69
+ end # create
70
+
71
+ end # schema
72
+
73
+
74
+ def migration_files
75
+ Dir.glob(File.join(Mack::Configuration.root, "db", "migrations", "*.rb"))
76
+ end
77
+
78
+ def migration_number(migration)
79
+ migration.match(/(^\d+)/).captures.last.to_i
80
+ end
81
+
82
+ def migration_name(migration)
83
+ migration.match(/^\d+_(.+)/).captures.last
84
+ end
85
+
86
+ end # db
data/test/database.yml ADDED
@@ -0,0 +1,3 @@
1
+ test:
2
+ adapter: sqlite3
3
+ database: <%= File.join(Mack::Configuration.root, "mack-active_record_test.db") %>
@@ -0,0 +1,9 @@
1
+ class AddUsers < ActiveRecord::Migration
2
+ def self.up
3
+ User.create(:username => "markbates", :email => "mark@mackframework.com")
4
+ end
5
+
6
+ def self.down
7
+ User.delete_all
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ class Album < ActiveRecord::Base
2
+
3
+ end
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + '/../test_helper.rb'
2
+
3
+ class AlbumTest < Test::Unit::TestCase
4
+
5
+ def test_truth
6
+ assert true
7
+ end
8
+
9
+ end