active_record_schema 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'rails', "~> 3.0"
4
+
5
+ group :development do
6
+ gem "jeweler", "~> 1.8.3"
7
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,92 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ actionmailer (3.2.3)
5
+ actionpack (= 3.2.3)
6
+ mail (~> 2.4.4)
7
+ actionpack (3.2.3)
8
+ activemodel (= 3.2.3)
9
+ activesupport (= 3.2.3)
10
+ builder (~> 3.0.0)
11
+ erubis (~> 2.7.0)
12
+ journey (~> 1.0.1)
13
+ rack (~> 1.4.0)
14
+ rack-cache (~> 1.2)
15
+ rack-test (~> 0.6.1)
16
+ sprockets (~> 2.1.2)
17
+ activemodel (3.2.3)
18
+ activesupport (= 3.2.3)
19
+ builder (~> 3.0.0)
20
+ activerecord (3.2.3)
21
+ activemodel (= 3.2.3)
22
+ activesupport (= 3.2.3)
23
+ arel (~> 3.0.2)
24
+ tzinfo (~> 0.3.29)
25
+ activeresource (3.2.3)
26
+ activemodel (= 3.2.3)
27
+ activesupport (= 3.2.3)
28
+ activesupport (3.2.3)
29
+ i18n (~> 0.6)
30
+ multi_json (~> 1.0)
31
+ arel (3.0.2)
32
+ builder (3.0.0)
33
+ erubis (2.7.0)
34
+ git (1.2.5)
35
+ hike (1.2.1)
36
+ i18n (0.6.0)
37
+ jeweler (1.8.3)
38
+ bundler (~> 1.0)
39
+ git (>= 1.2.5)
40
+ rake
41
+ rdoc
42
+ journey (1.0.3)
43
+ json (1.7.0)
44
+ mail (2.4.4)
45
+ i18n (>= 0.4.0)
46
+ mime-types (~> 1.16)
47
+ treetop (~> 1.4.8)
48
+ mime-types (1.18)
49
+ multi_json (1.3.4)
50
+ polyglot (0.3.3)
51
+ rack (1.4.1)
52
+ rack-cache (1.2)
53
+ rack (>= 0.4)
54
+ rack-ssl (1.3.2)
55
+ rack
56
+ rack-test (0.6.1)
57
+ rack (>= 1.0)
58
+ rails (3.2.3)
59
+ actionmailer (= 3.2.3)
60
+ actionpack (= 3.2.3)
61
+ activerecord (= 3.2.3)
62
+ activeresource (= 3.2.3)
63
+ activesupport (= 3.2.3)
64
+ bundler (~> 1.0)
65
+ railties (= 3.2.3)
66
+ railties (3.2.3)
67
+ actionpack (= 3.2.3)
68
+ activesupport (= 3.2.3)
69
+ rack-ssl (~> 1.3.2)
70
+ rake (>= 0.8.7)
71
+ rdoc (~> 3.4)
72
+ thor (~> 0.14.6)
73
+ rake (0.9.2.2)
74
+ rdoc (3.12)
75
+ json (~> 1.4)
76
+ sprockets (2.1.3)
77
+ hike (~> 1.2)
78
+ rack (~> 1.0)
79
+ tilt (~> 1.1, != 1.3.0)
80
+ thor (0.14.6)
81
+ tilt (1.3.3)
82
+ treetop (1.4.10)
83
+ polyglot
84
+ polyglot (>= 0.3.1)
85
+ tzinfo (0.3.33)
86
+
87
+ PLATFORMS
88
+ ruby
89
+
90
+ DEPENDENCIES
91
+ jeweler (~> 1.8.3)
92
+ rails (~> 3.0)
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 mcasimir
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,110 @@
1
+ # ActiveRecordSchema
2
+
3
+ *ActiveRecordSchema* is an ActiveRecord extension that allows you to write the database schema for a model within the model itself and to generate migrations directly from models.
4
+
5
+ Unlike other libraries (eg. mini_record) ActiveRecordSchema is not an alternative to Rails migrations, but rather a tool to simplify their use enhancing their positive sides and contrasting their defects.
6
+
7
+ Install
8
+
9
+ gem 'active_record_schema', :git => "git@github.com:mcasimir/active_record_schema.git"
10
+
11
+ Update your bundle
12
+
13
+ bundle install
14
+
15
+ ## Usage
16
+
17
+ Create a model
18
+
19
+ class Post < ActiveRecord::Base
20
+ schema do
21
+
22
+ field :title
23
+ field :body, :as => :text
24
+ belongs_to :author, :class_name => "User"
25
+
26
+ end
27
+ end
28
+
29
+ Run a migration generator each time you want to commit changes to database
30
+
31
+ rails g migration init_posts_schema --from Post
32
+
33
+ Will generate the following migration
34
+
35
+ class InitPostsSchema < ActiveRecord::Migration
36
+ def change
37
+ add_column :posts, :title, :string
38
+ add_column :posts, :body, :text
39
+
40
+ add_column :author_id, :integer
41
+ index :author_id
42
+ end
43
+ end
44
+
45
+
46
+ ## Single Table Inheritance (STI)
47
+
48
+ _ex._
49
+
50
+ # content.rb
51
+ class Content < ActiveRecord::Base
52
+ schema(:inheritable => true) do
53
+ field :title
54
+
55
+ timestamps!
56
+ end
57
+ end
58
+
59
+ # article.rb
60
+ class Article < Content
61
+ schema do
62
+ field :body, :as => :text
63
+ end
64
+ end
65
+
66
+ # video.rb
67
+ class Video < Content
68
+ schema do
69
+ field :url
70
+ end
71
+ end
72
+
73
+
74
+ ## Contributing to active_record_schema
75
+
76
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
77
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
78
+ * Fork the project.
79
+ * Start a feature/bugfix branch.
80
+ * Commit and push until you are happy with your contribution.
81
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
82
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
83
+
84
+ ## Coming Soon
85
+
86
+ * Automatically generate migrations for Join tables for HBTM
87
+
88
+ ---
89
+
90
+ Copyright (c) 2012 mcasimir
91
+
92
+ Permission is hereby granted, free of charge, to any person obtaining
93
+ a copy of this software and associated documentation files (the
94
+ "Software"), to deal in the Software without restriction, including
95
+ without limitation the rights to use, copy, modify, merge, publish,
96
+ distribute, sublicense, and/or sell copies of the Software, and to
97
+ permit persons to whom the Software is furnished to do so, subject to
98
+ the following conditions:
99
+
100
+ The above copyright notice and this permission notice shall be
101
+ included in all copies or substantial portions of the Software.
102
+
103
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
104
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
105
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
106
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
107
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
108
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
109
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
110
+
data/Rakefile ADDED
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "active_record_schema"
18
+ gem.homepage = "http://github.com/mcasimir/active_record_schema"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{ActiveRecord extension allowing to write schema in models and to generate migrations from models}
21
+ gem.description = %Q{ActiveRecordSchema is an ActiveRecord extension that allows you to write the database schema for a model within the model itself and to generate migrations directly from models.}
22
+ gem.email = "maurizio.cas@gmail.com"
23
+ gem.authors = ["mcasimir"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,63 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "active_record_schema"
8
+ s.version = "0.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["mcasimir"]
12
+ s.date = "2012-05-06"
13
+ s.description = "ActiveRecordSchema is an ActiveRecord extension that allows you to write the database schema for a model within the model itself and to generate migrations directly from models."
14
+ s.email = "maurizio.cas@gmail.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ "Gemfile",
21
+ "Gemfile.lock",
22
+ "LICENSE.txt",
23
+ "README.md",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "active_record_schema.gemspec",
27
+ "lib/active_record_schema.rb",
28
+ "lib/active_record_schema/base.rb",
29
+ "lib/active_record_schema/dsl.rb",
30
+ "lib/active_record_schema/field.rb",
31
+ "lib/active_record_schema/index.rb",
32
+ "lib/active_record_schema/join.rb",
33
+ "lib/active_record_schema/railtie.rb",
34
+ "lib/active_record_schema/schema.rb",
35
+ "lib/active_record_schema/schema_diff.rb",
36
+ "lib/generators/active_record_schema.rb",
37
+ "lib/generators/active_record_schema/migration/migration_generator.rb",
38
+ "lib/generators/active_record_schema/migration/templates/migration.rb",
39
+ "lib/generators/active_record_schema/migration/templates/migration_from_model.rb.erb",
40
+ "lib/generators/active_record_schema/model/model_generator.rb"
41
+ ]
42
+ s.homepage = "http://github.com/mcasimir/active_record_schema"
43
+ s.licenses = ["MIT"]
44
+ s.require_paths = ["lib"]
45
+ s.rubygems_version = "1.8.24"
46
+ s.summary = "ActiveRecord extension allowing to write schema in models and to generate migrations from models"
47
+
48
+ if s.respond_to? :specification_version then
49
+ s.specification_version = 3
50
+
51
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
52
+ s.add_runtime_dependency(%q<rails>, ["~> 3.0"])
53
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
54
+ else
55
+ s.add_dependency(%q<rails>, ["~> 3.0"])
56
+ s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
57
+ end
58
+ else
59
+ s.add_dependency(%q<rails>, ["~> 3.0"])
60
+ s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
61
+ end
62
+ end
63
+
@@ -0,0 +1,26 @@
1
+ require 'rails'
2
+ require 'ostruct'
3
+
4
+ module ActiveRecordSchema
5
+
6
+ def config
7
+ @config ||= OpenStruct.new
8
+ @config.autoload_paths ||= [
9
+ Rails.root.join('app', 'models', '*.rb'),
10
+ Rails.root.join('app', 'models', '**', '*.rb')
11
+ ]
12
+ @config
13
+ end
14
+ module_function :config
15
+
16
+ def autoload_paths
17
+ config.autoload_paths.map {|p| Dir.glob(p) }.flatten!
18
+ end
19
+ module_function :autoload_paths
20
+
21
+ end
22
+
23
+ require 'active_record_schema/base'
24
+ require 'active_record_schema/railtie'
25
+
26
+ ActiveRecord::Base.send(:include, ActiveRecordSchema::Base)
@@ -0,0 +1,8 @@
1
+ require 'active_record_schema/dsl'
2
+
3
+ module ActiveRecordSchema
4
+ module Base
5
+ extend ActiveSupport::Concern
6
+ include ActiveRecordSchema::Dsl
7
+ end
8
+ end
@@ -0,0 +1,86 @@
1
+ require 'active_record_schema/schema'
2
+
3
+ module ActiveRecordSchema
4
+ module Dsl
5
+ extend ActiveSupport::Concern
6
+ module ClassMethods
7
+
8
+ def schema
9
+ if self.superclass != ActiveRecord::Base
10
+ table_holder = self.ancestors.find {|c| c.is_a?(Class) && c.superclass == ActiveRecord::Base}
11
+ table_holder.schema
12
+ else
13
+ @active_record_schema_schema ||= ActiveRecordSchema::Schema.new(self)
14
+ end
15
+ end # ~ schema
16
+
17
+ # field :name, :string, :default => "Joe"
18
+ def field(name, *args)
19
+ options = args.extract_options!
20
+ type = options.delete(:as) || options.delete(:type) || args.first || :string
21
+ type = type.name.underscore.to_sym if (type.class == Class)
22
+ index = options.delete(:index)
23
+
24
+ schema.add_field(name, type, options)
25
+
26
+ if index
27
+ schema.add_index(name)
28
+ end
29
+ end
30
+ alias :key :field
31
+ alias :property :field
32
+ alias :col :field
33
+
34
+ def belongs_to(name, options = {})
35
+ options.symbolize_keys!
36
+ skip_index = options.delete(:index) == false
37
+
38
+ foreign_key = options[:foreign_key] || "#{name}_id"
39
+ field :"#{foreign_key}"
40
+
41
+ if options[:polimorphic]
42
+ foreign_type = options[:foreign_type] || "#{name}_type"
43
+ field :"#{foreign_type}"
44
+ add_index [:"#{foreign_key}", :"#{foreign_type}"] if !skip_index
45
+ else
46
+ add_index :"#{foreign_key}" if !skip_index
47
+ end
48
+
49
+ super(name, options)
50
+ end
51
+
52
+ def has_and_belongs_to_many(name, options = {}, &extension)
53
+ options.symbolize_keys!
54
+
55
+ self_class_name = self.name
56
+ association_class_name = options[:class_name] || "#{name}".singularize.camelize
57
+
58
+ table = options[:join_table] || [self_class_name, association_class_name].sort.map(&:tableize).join("_")
59
+ key1 = options[:foreign_key] || "#{self_class_name.underscore}_id"
60
+ key2 = options[:association_foreign_key] || "#{association_class_name.underscore}_id"
61
+ skip_index = options.delete(:index) == false
62
+
63
+ schema.add_join(table, key1, key2, !skip_index)
64
+ super(name, options, &extension)
65
+ end
66
+
67
+ def add_index(column_name, options = {})
68
+ schema.add_index(column_name, options)
69
+ end
70
+ alias :index :add_index
71
+
72
+ def timestamps!
73
+ field :created_at, :datetime
74
+ field :updated_at, :datetime
75
+ end
76
+ alias :timestamps :timestamps!
77
+
78
+ def inheritable!
79
+ field :"#{inheritance_column}"
80
+ end
81
+ alias :inheritable :inheritable!
82
+
83
+ end
84
+
85
+ end
86
+ end
@@ -0,0 +1,10 @@
1
+ module ActiveRecordSchema
2
+ class Field
3
+ attr_reader :name, :type, :options
4
+ def initialize(name, type, options = {})
5
+ @name = name
6
+ @type = type
7
+ @options = options
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module ActiveRecordSchema
2
+ class Index
3
+ attr_reader :name, :options
4
+ def initialize(name, options = {})
5
+ @name = name
6
+ @options = options
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module ActiveRecordSchema
2
+ class Join
3
+ attr_reader :table, :key1, :key2, :index
4
+ def initialize(table, key1, key2, index = true)
5
+ @table = table
6
+ @key1 = key1
7
+ @key2 = key2
8
+ @index = index
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ module ActiveRecordSchema
2
+ class Railtie < Rails::Railtie
3
+ config.app_generators.orm :active_record_schema
4
+ end
5
+ end
@@ -0,0 +1,36 @@
1
+ require 'active_record_schema/field'
2
+ require 'active_record_schema/index'
3
+ require 'active_record_schema/join'
4
+ require 'active_record_schema/schema_diff'
5
+
6
+ module ActiveRecordSchema
7
+ class Schema
8
+ include ActiveRecordSchema::SchemaDiff
9
+
10
+ attr_reader :model, :fields, :indexes, :joins
11
+
12
+ def initialize(model)
13
+ @model = model
14
+ @fields = {}
15
+ @indexes = {}
16
+ @joins = {}
17
+ end
18
+
19
+ def field_names
20
+ fields.values.map(&:name).map(&:to_s)
21
+ end
22
+
23
+ def add_field(column, type, options)
24
+ @fields[:"#{column}"] = Field.new(column, type, options)
25
+ end
26
+
27
+ def add_index(column, options = {})
28
+ @indexes[:"#{column}"] = Index.new(column, options)
29
+ end
30
+
31
+ def add_join(table, key1, key2, index = true)
32
+ @joins[:"#{table}"] = Join.new(table, key1, key2)
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,44 @@
1
+ module ActiveRecordSchema
2
+ module SchemaDiff
3
+ extend ActiveSupport::Concern
4
+
5
+ def diff(*args)
6
+ diff_method = "_diff_" << args.join('_')
7
+ self.respond_to?(diff_method) ? self.send(diff_method) : []
8
+ end
9
+
10
+ def _diff_fields_add
11
+ model.schema.fields.values.delete_if {|field| _column_names.include?(field.name.to_s) }
12
+ end
13
+
14
+ def _diff_indexes_add
15
+ model.schema.indexes.values.delete_if {|index| _index_names.include?(index.name.to_s) }
16
+ end
17
+
18
+ def _diff_joins_add
19
+ model.schema.joins.values.delete_if {|join| _table_names.include?(join.table.to_s) }
20
+ end
21
+
22
+
23
+ def _connection
24
+ ActiveRecord::Base.connection
25
+ end
26
+
27
+ def _table
28
+ model.table_name
29
+ end
30
+
31
+ def _column_names
32
+ _connection.columns(_table).map(&:name)
33
+ end
34
+
35
+ def _index_names
36
+ _connection.indexes(_table).map(&:name)
37
+ end
38
+
39
+ def _table_names
40
+ _connection.tables
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,22 @@
1
+ require 'rails/generators/named_base'
2
+ require 'rails/generators/migration'
3
+ require 'rails/generators/active_model'
4
+
5
+ module ActiveRecordSchema
6
+ module Generators
7
+ class Base < ::Rails::Generators::NamedBase
8
+
9
+ include Rails::Generators::Migration
10
+
11
+ def self.base_root
12
+ File.dirname(__FILE__)
13
+ end
14
+
15
+ def self.next_migration_number(dirname) #:nodoc:
16
+ next_migration_number = current_migration_number(dirname) + 1
17
+ ActiveRecord::Migration.next_migration_number(next_migration_number)
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,49 @@
1
+ require 'generators/active_record_schema'
2
+
3
+ module ActiveRecordSchema
4
+ module Generators
5
+ class MigrationGenerator < Base
6
+ source_root File.expand_path('../templates', __FILE__)
7
+ argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
8
+ class_option :from, :type => :string, :desc => "calculates the changes to be applied on model table from the schema defined inside the model itself"
9
+ class_option :id, :type => :numeric, :desc => "The id to be used in this migration"
10
+
11
+ def create_migration_file
12
+ set_local_assigns!
13
+ if options[:from]
14
+ # preload every model
15
+ ActiveRecordSchema.autoload_paths.each do |p|
16
+ load(p)
17
+ end
18
+
19
+ migration_template "migration_from_model.rb.erb", "db/migrate/#{file_name}.rb"
20
+ else
21
+ migration_template "migration.rb", "db/migrate/#{file_name}.rb"
22
+ end
23
+ end
24
+
25
+ protected
26
+
27
+
28
+ def model
29
+ @model ||= if !!options[:from]
30
+ options[:from].constantize
31
+ else
32
+ false
33
+ end
34
+ end
35
+
36
+ attr_reader :migration_action
37
+
38
+ def set_local_assigns!
39
+ if file_name =~ /^(add|remove|drop)_.*_(?:to|from)_(.*)/
40
+ @migration_action = $1 == 'add' ? 'add' : 'drop'
41
+ @table_name = $2.pluralize
42
+ end
43
+ end
44
+
45
+
46
+ end
47
+ end
48
+ end
49
+
@@ -0,0 +1,34 @@
1
+ class <%= migration_class_name %> < ActiveRecord::Migration
2
+ <%- if migration_action == 'add' -%>
3
+ def change
4
+ <% attributes.each do |attribute| -%>
5
+ add_column :<%= table_name %>, :<%= attribute.name %>, :<%= attribute.type %><%= attribute.inject_options %>
6
+ <%- if attribute.has_index? -%>
7
+ add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
8
+ <%- end -%>
9
+ <%- end -%>
10
+ end
11
+ <%- else -%>
12
+ def up
13
+ <% attributes.each do |attribute| -%>
14
+ <%- if migration_action -%>
15
+ <%= migration_action %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'add' %>, :<%= attribute.type %><%= attribute.inject_options %><% end %>
16
+ <%- if attribute.has_index? && migration_action == 'add' -%>
17
+ add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
18
+ <%- end -%>
19
+ <%- end -%>
20
+ <%- end -%>
21
+ end
22
+
23
+ def down
24
+ <% attributes.reverse.each do |attribute| -%>
25
+ <%- if migration_action -%>
26
+ <%= migration_action == 'add' ? 'remove' : 'add' %>_column :<%= table_name %>, :<%= attribute.name %><% if migration_action == 'remove' %>, :<%= attribute.type %><%= attribute.inject_options %><% end %>
27
+ <%- if attribute.has_index? && migration_action == 'remove' -%>
28
+ add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
29
+ <%- end -%>
30
+ <%- end -%>
31
+ <%- end -%>
32
+ end
33
+ <%- end -%>
34
+ end
@@ -0,0 +1,22 @@
1
+ class <%= migration_class_name %> < ActiveRecord::Migration
2
+ def change
3
+ <%- model.schema.diff(:fields, :add).each do |field| -%>
4
+ add_column :<%= model.table_name %>, <%= field.name.inspect %>, <%= field.type.inspect %><%= ", #{field.options.inspect}" if !field.options.blank? %>
5
+ <%- end -%>
6
+
7
+ <%- model.schema.diff(:indexes, :add).each do |index| -%>
8
+ add_index :<%= model.table_name %>, <%= index.name.inspect %><%= ", #{index.options.inspect}" if !index.options.blank? %>
9
+ <%- end -%>
10
+
11
+ <%- model.schema.diff(:joins, :add).each do |join| -%>
12
+ create_table :<%= join.table %>, :id => false do |t|
13
+ t.integer <%= join.key1.inspect %>
14
+ t.integer <%= join.key2.inspect %>
15
+ end
16
+ <%- if join.index -%>
17
+ add_index :<%= join.table %>, <%= join.key1.inspect %>
18
+ add_index :<%= join.table %>, <%= join.key2.inspect %>
19
+ <%- end -%>
20
+ <%- end -%>
21
+ end
22
+ end
@@ -0,0 +1,32 @@
1
+ require 'generators/active_record_schema'
2
+
3
+ module ActiveRecordSchema
4
+ module Generators
5
+ class ModelGenerator < Base
6
+ class_option :in, :type => :string
7
+ class_option :inherit, :type => :string, :default => 'ActiveRecord::Base'
8
+ class_option :from
9
+
10
+ def create_model_file
11
+ create_file ["app", "models", subdir, "#{file_name}.rb"].compact.join('/'), <<-FILE
12
+ class #{class_name} < #{ inherit }
13
+ end
14
+ FILE
15
+ end
16
+
17
+ private
18
+
19
+ def subdir
20
+ in_opt = "#{options[:in]}".strip
21
+ in_opt.empty? || in_opt.match(/\//) ? nil : in_opt
22
+ end
23
+
24
+ def inherit
25
+ options[:inherit]
26
+ end
27
+
28
+
29
+ end
30
+ end
31
+ end
32
+
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_record_schema
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - mcasimir
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: jeweler
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 1.8.3
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.8.3
46
+ description: ActiveRecordSchema is an ActiveRecord extension that allows you to write
47
+ the database schema for a model within the model itself and to generate migrations
48
+ directly from models.
49
+ email: maurizio.cas@gmail.com
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files:
53
+ - LICENSE.txt
54
+ - README.md
55
+ files:
56
+ - Gemfile
57
+ - Gemfile.lock
58
+ - LICENSE.txt
59
+ - README.md
60
+ - Rakefile
61
+ - VERSION
62
+ - active_record_schema.gemspec
63
+ - lib/active_record_schema.rb
64
+ - lib/active_record_schema/base.rb
65
+ - lib/active_record_schema/dsl.rb
66
+ - lib/active_record_schema/field.rb
67
+ - lib/active_record_schema/index.rb
68
+ - lib/active_record_schema/join.rb
69
+ - lib/active_record_schema/railtie.rb
70
+ - lib/active_record_schema/schema.rb
71
+ - lib/active_record_schema/schema_diff.rb
72
+ - lib/generators/active_record_schema.rb
73
+ - lib/generators/active_record_schema/migration/migration_generator.rb
74
+ - lib/generators/active_record_schema/migration/templates/migration.rb
75
+ - lib/generators/active_record_schema/migration/templates/migration_from_model.rb.erb
76
+ - lib/generators/active_record_schema/model/model_generator.rb
77
+ homepage: http://github.com/mcasimir/active_record_schema
78
+ licenses:
79
+ - MIT
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ segments:
91
+ - 0
92
+ hash: 1365904965282049359
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubyforge_project:
101
+ rubygems_version: 1.8.24
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: ActiveRecord extension allowing to write schema in models and to generate
105
+ migrations from models
106
+ test_files: []