schema_comments 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/LICENSE.txt +60 -0
- data/README +149 -0
- data/Rakefile +46 -0
- data/VERSION +1 -0
- data/autotest/discover.rb +10 -0
- data/init.rb +4 -0
- data/lib/annotate_models.rb +224 -0
- data/lib/schema_comments/base.rb +72 -0
- data/lib/schema_comments/connection_adapters.rb +170 -0
- data/lib/schema_comments/migration.rb +20 -0
- data/lib/schema_comments/migrator.rb +20 -0
- data/lib/schema_comments/schema.rb +20 -0
- data/lib/schema_comments/schema_comment.rb +195 -0
- data/lib/schema_comments/schema_dumper.rb +160 -0
- data/lib/schema_comments.rb +53 -0
- data/spec/.gitignore +3 -0
- data/spec/annotate_models_spec.rb +56 -0
- data/spec/database.yml +13 -0
- data/spec/fixtures/.gitignore +0 -0
- data/spec/i18n_export_spec.rb +48 -0
- data/spec/migration_spec.rb +96 -0
- data/spec/migrations/valid/001_create_products.rb +17 -0
- data/spec/migrations/valid/002_rename_products.rb +10 -0
- data/spec/migrations/valid/003_rename_products_again.rb +10 -0
- data/spec/migrations/valid/004_remove_price.rb +10 -0
- data/spec/migrations/valid/005_change_products_name.rb +10 -0
- data/spec/migrations/valid/006_change_products_name_with_comment.rb +10 -0
- data/spec/resources/models/product.rb +2 -0
- data/spec/resources/models/product_name.rb +2 -0
- data/spec/schema.rb +2 -0
- data/spec/schema_dumper_spec.rb +74 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +46 -0
- data/spec/yaml_export_spec.rb +52 -0
- data/tasks/annotate_models_tasks.rake +12 -0
- data/tasks/schema_comments.rake +204 -0
- metadata +115 -0
@@ -0,0 +1,160 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module SchemaComments
|
3
|
+
module SchemaDumper
|
4
|
+
def self.included(mod)
|
5
|
+
# mod.extend(ClassMethods)
|
6
|
+
# mod.instance_eval do
|
7
|
+
# alias :ignore_tables_without_schema_comments :ignore_tables
|
8
|
+
# alias :ignore_tables :ignore_tables_with_schema_comments
|
9
|
+
# end
|
10
|
+
mod.module_eval do
|
11
|
+
alias_method_chain :tables, :schema_comments
|
12
|
+
alias_method_chain :table, :schema_comments
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
IGNORED_TABLE = 'schema_comments'
|
17
|
+
|
18
|
+
# module ClassMethods
|
19
|
+
# def ignore_tables_with_schema_comments
|
20
|
+
# result = ignore_tables_without_schema_comments
|
21
|
+
# result << IGNORED_TABLE unless result.include?(IGNORED_TABLE)
|
22
|
+
# result
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
|
26
|
+
private
|
27
|
+
def tables_with_schema_comments(stream)
|
28
|
+
tables_without_schema_comments(stream)
|
29
|
+
if adapter_name == "mysql"
|
30
|
+
# ビューはtableの後に実行するようにしないと rake db:schema:load で失敗します。
|
31
|
+
mysql_views(stream)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def table_with_schema_comments(table, stream)
|
36
|
+
return if IGNORED_TABLE == table.downcase
|
37
|
+
# MySQLは、ビューもテーブルとして扱うので、一個一個チェックします。
|
38
|
+
if adapter_name == 'mysql'
|
39
|
+
config = ActiveRecord::Base.configurations[RAILS_ENV]
|
40
|
+
match_count = @connection.select_value(
|
41
|
+
"select count(*) from information_schema.TABLES where TABLE_TYPE = 'VIEW' AND TABLE_SCHEMA = '%s' AND TABLE_NAME = '%s'" % [
|
42
|
+
config["database"], table])
|
43
|
+
return if match_count.to_i > 0
|
44
|
+
end
|
45
|
+
columns = @connection.columns(table)
|
46
|
+
begin
|
47
|
+
tbl = StringIO.new
|
48
|
+
|
49
|
+
if @connection.respond_to?(:pk_and_sequence_for)
|
50
|
+
pk, pk_seq = @connection.pk_and_sequence_for(table)
|
51
|
+
end
|
52
|
+
pk ||= 'id'
|
53
|
+
|
54
|
+
tbl.print " create_table #{table.inspect}"
|
55
|
+
if columns.detect { |c| c.name == pk }
|
56
|
+
if pk != 'id'
|
57
|
+
tbl.print %Q(, :primary_key => "#{pk}")
|
58
|
+
end
|
59
|
+
else
|
60
|
+
tbl.print ", :id => false"
|
61
|
+
end
|
62
|
+
tbl.print ", :force => true"
|
63
|
+
|
64
|
+
table_comment = @connection.table_comment(table)
|
65
|
+
tbl.print ", :comment => '#{table_comment}'" unless table_comment.blank?
|
66
|
+
|
67
|
+
tbl.puts " do |t|"
|
68
|
+
|
69
|
+
column_specs = columns.map do |column|
|
70
|
+
raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" if @types[column.type].nil?
|
71
|
+
next if column.name == pk
|
72
|
+
spec = {}
|
73
|
+
spec[:name] = column.name.inspect
|
74
|
+
spec[:type] = column.type.to_s
|
75
|
+
spec[:limit] = column.limit.inspect if column.limit != @types[column.type][:limit] && column.type != :decimal
|
76
|
+
spec[:precision] = column.precision.inspect if !column.precision.nil?
|
77
|
+
spec[:scale] = column.scale.inspect if !column.scale.nil?
|
78
|
+
spec[:null] = 'false' if !column.null
|
79
|
+
spec[:default] = default_string(column.default) if !column.default.nil?
|
80
|
+
spec[:comment] = (column.comment || '').inspect
|
81
|
+
(spec.keys - [:name, :type]).each{ |k| spec[k].insert(0, "#{k.inspect} => ")}
|
82
|
+
spec
|
83
|
+
end.compact
|
84
|
+
|
85
|
+
# find all migration keys used in this table
|
86
|
+
keys = [:name, :limit, :precision, :scale, :default, :null, :comment] & column_specs.map(&:keys).flatten
|
87
|
+
|
88
|
+
# figure out the lengths for each column based on above keys
|
89
|
+
lengths = keys.map{ |key| column_specs.map{ |spec| spec[key] ? spec[key].length + 2 : 0 }.max }
|
90
|
+
|
91
|
+
# the string we're going to sprintf our values against, with standardized column widths
|
92
|
+
format_string = lengths.map{ |len| "%-#{len}s" }
|
93
|
+
|
94
|
+
# find the max length for the 'type' column, which is special
|
95
|
+
type_length = column_specs.map{ |column| column[:type].length }.max
|
96
|
+
|
97
|
+
# add column type definition to our format string
|
98
|
+
format_string.unshift " t.%-#{type_length}s "
|
99
|
+
|
100
|
+
format_string *= ''
|
101
|
+
|
102
|
+
column_specs.each do |colspec|
|
103
|
+
values = keys.zip(lengths).map{ |key, len| colspec.key?(key) ? colspec[key] + ", " : " " * len }
|
104
|
+
values.unshift colspec[:type]
|
105
|
+
tbl.print((format_string % values).gsub(/,\s*$/, ''))
|
106
|
+
tbl.puts
|
107
|
+
end
|
108
|
+
|
109
|
+
tbl.puts " end"
|
110
|
+
tbl.puts
|
111
|
+
|
112
|
+
indexes(table, tbl)
|
113
|
+
|
114
|
+
tbl.rewind
|
115
|
+
stream.print tbl.read
|
116
|
+
rescue => e
|
117
|
+
stream.puts "# Could not dump table #{table.inspect} because of following #{e.class}"
|
118
|
+
stream.puts "# #{e.message}"
|
119
|
+
stream.puts
|
120
|
+
end
|
121
|
+
|
122
|
+
stream
|
123
|
+
end
|
124
|
+
|
125
|
+
def adapter_name
|
126
|
+
config = ActiveRecord::Base.configurations[RAILS_ENV]
|
127
|
+
config ? config['adapter'] : ActiveRecord::Base.connection.adapter_name
|
128
|
+
end
|
129
|
+
|
130
|
+
def mysql_views(stream)
|
131
|
+
config = ActiveRecord::Base.configurations[RAILS_ENV]
|
132
|
+
view_names = @connection.select_values(
|
133
|
+
"select TABLE_NAME from information_schema.TABLES where TABLE_TYPE = 'VIEW' AND TABLE_SCHEMA = '%s'" % config["database"])
|
134
|
+
view_names.each do |view_name|
|
135
|
+
mysql_view(view_name, stream)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def mysql_view(view_name, stream)
|
140
|
+
ddl = @connection.select_value("show create view #{view_name}")
|
141
|
+
ddl.gsub!(/^CREATE .+? VIEW /i, "CREATE OR REPLACE VIEW ")
|
142
|
+
ddl.gsub!(/AS select/, "AS \n select\n")
|
143
|
+
ddl.gsub!(/( AS \`.+?\`\,)/){ "#{$1}\n" }
|
144
|
+
ddl.gsub!(/ from /i , "\n from \n")
|
145
|
+
ddl.gsub!(/ where /i , "\n where \n")
|
146
|
+
ddl.gsub!(/ order by /i , "\n order by \n")
|
147
|
+
ddl.gsub!(/ having /i , "\n having \n")
|
148
|
+
ddl.gsub!(/ union /i , "\n union \n")
|
149
|
+
ddl.gsub!(/ and /i , "\n and ")
|
150
|
+
ddl.gsub!(/ or /i , "\n or ")
|
151
|
+
ddl.gsub!(/inner join/i , "\n inner join")
|
152
|
+
ddl.gsub!(/left join/i , "\n left join")
|
153
|
+
ddl.gsub!(/left outer join/i, "\n left outer join")
|
154
|
+
stream.print(" ActiveRecord::Base.connection.execute(<<-EOS)\n")
|
155
|
+
stream.print(ddl.split(/\n/).map{|line| ' ' << line.strip}.join("\n"))
|
156
|
+
stream.print("\n EOS\n")
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module SchemaComments
|
2
|
+
VERSION = '0.1.0'
|
3
|
+
|
4
|
+
autoload :Base, 'schema_comments/base'
|
5
|
+
autoload :ConnectionAdapters, 'schema_comments/connection_adapters'
|
6
|
+
autoload :Migration, 'schema_comments/migration'
|
7
|
+
autoload :Migrator, 'schema_comments/migrator'
|
8
|
+
autoload :Schema, 'schema_comments/schema'
|
9
|
+
autoload :SchemaComment, 'schema_comments/schema_comment'
|
10
|
+
autoload :SchemaDumper, 'schema_comments/schema_dumper'
|
11
|
+
|
12
|
+
DEFAULT_YAML_PATH = File.expand_path(File.join(RAILS_ROOT, 'db/schema_comments.yml'))
|
13
|
+
|
14
|
+
mattr_accessor :yaml_path
|
15
|
+
self.yaml_path = DEFAULT_YAML_PATH
|
16
|
+
|
17
|
+
mattr_accessor :quiet
|
18
|
+
|
19
|
+
class << self
|
20
|
+
def setup
|
21
|
+
base_names = %w(Base Migration Migrator Schema SchemaDumper) +
|
22
|
+
%w(Column ColumnDefinition TableDefinition).map{|name| "ConnectionAdapters::#{name}"}
|
23
|
+
|
24
|
+
base_names.each do |base_name|
|
25
|
+
ar_class = "ActiveRecord::#{base_name}".constantize
|
26
|
+
sc_class = "SchemaComments::#{base_name}".constantize
|
27
|
+
unless ar_class.ancestors.include?(sc_class)
|
28
|
+
ar_class.__send__(:include, sc_class)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
unless ActiveRecord::ConnectionAdapters::AbstractAdapter.ancestors.include?(SchemaComments::ConnectionAdapters::Adapter)
|
33
|
+
ActiveRecord::ConnectionAdapters::AbstractAdapter.module_eval do
|
34
|
+
include SchemaComments::ConnectionAdapters::Adapter
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# %w(Mysql PostgreSQL SQLite3 SQLite Firebird DB2 Oracle Sybase Openbase Frontbase)
|
39
|
+
%w(Mysql PostgreSQL SQLite3 SQLite).each do |adapter|
|
40
|
+
begin
|
41
|
+
require("active_record/connection_adapters/#{adapter.downcase}_adapter")
|
42
|
+
adapter_class = ('ActiveRecord::ConnectionAdapters::' << "#{adapter}Adapter").constantize
|
43
|
+
adapter_class.module_eval do
|
44
|
+
include SchemaComments::ConnectionAdapters::ConcreteAdapter
|
45
|
+
end
|
46
|
+
rescue Exception => e
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
data/spec/.gitignore
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
3
|
+
|
4
|
+
require File.join(File.dirname(__FILE__), '../lib/annotate_models.rb')
|
5
|
+
|
6
|
+
describe AnnotateModels do
|
7
|
+
|
8
|
+
before(:each) do
|
9
|
+
SchemaComments.yaml_path = File.expand_path(File.join(File.dirname(__FILE__), 'schema_comments.yml'))
|
10
|
+
FileUtils.rm(SchemaComments.yaml_path, :verbose => true) if File.exist?(SchemaComments.yaml_path)
|
11
|
+
|
12
|
+
(ActiveRecord::Base.connection.tables - IGNORED_TABLES).each do |t|
|
13
|
+
ActiveRecord::Base.connection.drop_table(t) rescue nil
|
14
|
+
end
|
15
|
+
ActiveRecord::Base.connection.initialize_schema_migrations_table
|
16
|
+
ActiveRecord::Base.connection.execute "DELETE FROM #{ActiveRecord::Migrator.schema_migrations_table_name}"
|
17
|
+
end
|
18
|
+
|
19
|
+
it "get_schema_info" do
|
20
|
+
(ActiveRecord::Base.connection.tables - %w(schema_migrations)).should == []
|
21
|
+
|
22
|
+
ActiveRecord::Schema.define(:version => "20090721185959") do
|
23
|
+
drop_table("books") rescue nil
|
24
|
+
|
25
|
+
create_table "books", :force => true, :comment => '書籍' do |t|
|
26
|
+
t.string "title", :limit => 100, :null => false, :comment => 'タイトル'
|
27
|
+
t.integer "size", :null => false, :default => 1, :comment => '判型'
|
28
|
+
t.decimal "price", :precision => 17, :scale => 14, :default => 0.0, :null => false, :comment => '価格'
|
29
|
+
t.datetime "created_at", :comment => '登録日時'
|
30
|
+
t.datetime "updated_at", :comment => '更新日時'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Book < ActiveRecord::Base
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
AnnotateModels.get_schema_info(Book).should == %{# == Schema Info ==
|
39
|
+
#
|
40
|
+
# Schema version: 20090721185959
|
41
|
+
#
|
42
|
+
# Table name: books # 書籍
|
43
|
+
#
|
44
|
+
# id :integer not null, primary key
|
45
|
+
# title :string(100) not null # タイトル
|
46
|
+
# size :integer not null, default(1) # 判型
|
47
|
+
# price :decimal(17, 14) not null, default(0.0) # 価格
|
48
|
+
# created_at :datetime # 登録日時
|
49
|
+
# updated_at :datetime # 更新日時
|
50
|
+
#
|
51
|
+
# =================
|
52
|
+
#
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
data/spec/database.yml
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
sqlite:
|
2
|
+
:adapter: sqlite
|
3
|
+
:dbfile: schema_comments_test.sqlite.db
|
4
|
+
sqlite3:
|
5
|
+
:adapter: sqlite3
|
6
|
+
:database: schema_comments_test.sqlite3.db
|
7
|
+
mysql:
|
8
|
+
adapter: mysql
|
9
|
+
encoding: utf8
|
10
|
+
username: root
|
11
|
+
password:
|
12
|
+
socket: /opt/local/var/run/mysql5/mysqld.sock
|
13
|
+
database: schema_comments_test
|
File without changes
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
3
|
+
|
4
|
+
describe SchemaComments::Base do
|
5
|
+
|
6
|
+
MIGRATIONS_ROOT = File.join(File.dirname(__FILE__), 'migrations')
|
7
|
+
|
8
|
+
IGNORED_TABLES = %w(schema_migrations)
|
9
|
+
|
10
|
+
before(:each) do
|
11
|
+
SchemaComments.yaml_path = File.expand_path(File.join(File.dirname(__FILE__), 'schema_comments.yml'))
|
12
|
+
FileUtils.rm(SchemaComments.yaml_path, :verbose => true) if File.exist?(SchemaComments.yaml_path)
|
13
|
+
|
14
|
+
(ActiveRecord::Base.connection.tables - IGNORED_TABLES).each do |t|
|
15
|
+
ActiveRecord::Base.connection.drop_table(t) rescue nil
|
16
|
+
end
|
17
|
+
ActiveRecord::Base.connection.initialize_schema_migrations_table
|
18
|
+
ActiveRecord::Base.connection.execute "DELETE FROM #{ActiveRecord::Migrator.schema_migrations_table_name}"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "test_valid_migration" do
|
22
|
+
(ActiveRecord::Base.connection.tables - %w(schema_migrations)).should == []
|
23
|
+
|
24
|
+
migration_path = File.join(MIGRATIONS_ROOT, 'valid')
|
25
|
+
Dir.glob('*.rb').each do |file|
|
26
|
+
require(file) if /^\d+?_.*/ =~ file
|
27
|
+
end
|
28
|
+
|
29
|
+
Product.reset_table_comments
|
30
|
+
Product.reset_column_comments
|
31
|
+
|
32
|
+
ActiveRecord::Migrator.up(migration_path, 1)
|
33
|
+
ActiveRecord::Migrator.current_version.should == 1
|
34
|
+
|
35
|
+
ActiveRecord::Base.export_i18n_models.keys.include?('product').should == true
|
36
|
+
ActiveRecord::Base.export_i18n_models['product'].should == '商品'
|
37
|
+
|
38
|
+
ActiveRecord::Base.export_i18n_attributes.keys.include?('product').should == true
|
39
|
+
ActiveRecord::Base.export_i18n_attributes['product'].should == {
|
40
|
+
'product_type_cd' => '種別コード',
|
41
|
+
"price" => "価格",
|
42
|
+
"name" => "商品名",
|
43
|
+
"created_at" => "登録日時",
|
44
|
+
"updated_at" => "更新日時"
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
3
|
+
|
4
|
+
describe ActiveRecord::Migrator do
|
5
|
+
|
6
|
+
MIGRATIONS_ROOT = File.join(File.dirname(__FILE__), 'migrations')
|
7
|
+
|
8
|
+
IGNORED_TABLES = %w(schema_migrations)
|
9
|
+
|
10
|
+
before(:each) do
|
11
|
+
SchemaComments.yaml_path = File.expand_path(File.join(File.dirname(__FILE__), 'schema_comments.yml'))
|
12
|
+
FileUtils.rm(SchemaComments.yaml_path, :verbose => true) if File.exist?(SchemaComments.yaml_path)
|
13
|
+
|
14
|
+
(ActiveRecord::Base.connection.tables - IGNORED_TABLES).each do |t|
|
15
|
+
ActiveRecord::Base.connection.drop_table(t) rescue nil
|
16
|
+
end
|
17
|
+
ActiveRecord::Base.connection.initialize_schema_migrations_table
|
18
|
+
ActiveRecord::Base.connection.execute "DELETE FROM #{ActiveRecord::Migrator.schema_migrations_table_name}"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "test_valid_migration" do
|
22
|
+
(ActiveRecord::Base.connection.tables - %w(schema_migrations)).should == []
|
23
|
+
|
24
|
+
migration_path = File.join(MIGRATIONS_ROOT, 'valid')
|
25
|
+
Dir.glob('*.rb').each do |file|
|
26
|
+
require(file) if /^\d+?_.*/ =~ file
|
27
|
+
end
|
28
|
+
|
29
|
+
Product.reset_table_comments
|
30
|
+
Product.reset_column_comments
|
31
|
+
|
32
|
+
ActiveRecord::Migrator.up(migration_path, 1)
|
33
|
+
|
34
|
+
ActiveRecord::Migrator.current_version.should == 1
|
35
|
+
Product.table_comment.should == '商品'
|
36
|
+
{
|
37
|
+
'product_type_cd' => '種別コード',
|
38
|
+
"price" => "価格",
|
39
|
+
"name" => "商品名",
|
40
|
+
"created_at" => "登録日時",
|
41
|
+
"updated_at" => "更新日時"
|
42
|
+
}.each do |col_name, comment|
|
43
|
+
Product.columns.detect{|c| c.name.to_s == col_name}.comment.should == comment
|
44
|
+
end
|
45
|
+
|
46
|
+
ActiveRecord::Migrator.down(migration_path, 0)
|
47
|
+
# SchemaComments::SchemaComment.count.should == 0
|
48
|
+
|
49
|
+
ActiveRecord::Migrator.up(migration_path, 1)
|
50
|
+
ActiveRecord::Migrator.up(migration_path, 2)
|
51
|
+
ActiveRecord::Migrator.current_version.should == 2
|
52
|
+
|
53
|
+
ProductName.table_comment.should == '商品'
|
54
|
+
{
|
55
|
+
'product_type_cd' => '種別コード',
|
56
|
+
"price" => "価格",
|
57
|
+
"name" => "商品名",
|
58
|
+
"created_at" => "登録日時",
|
59
|
+
"updated_at" => "更新日時"
|
60
|
+
}.each do |col_name, comment|
|
61
|
+
ProductName.columns.detect{|c| c.name == col_name}.comment.should == comment
|
62
|
+
end
|
63
|
+
|
64
|
+
ActiveRecord::Migrator.down(migration_path, 1)
|
65
|
+
ActiveRecord::Migrator.current_version.should == 1
|
66
|
+
|
67
|
+
Product.table_comment.should == '商品'
|
68
|
+
{
|
69
|
+
'product_type_cd' => '種別コード',
|
70
|
+
"price" => "価格",
|
71
|
+
"name" => "商品名",
|
72
|
+
"created_at" => "登録日時",
|
73
|
+
"updated_at" => "更新日時"
|
74
|
+
}.each do |col_name, comment|
|
75
|
+
Product.columns.detect{|c| c.name == col_name}.comment.should == comment
|
76
|
+
end
|
77
|
+
|
78
|
+
ActiveRecord::Migrator.up(migration_path, 4)
|
79
|
+
ActiveRecord::Migrator.current_version.should == 4
|
80
|
+
# SchemaComments::SchemaComment.count.should == 5
|
81
|
+
|
82
|
+
ActiveRecord::Migrator.down(migration_path, 3)
|
83
|
+
ActiveRecord::Migrator.current_version.should == 3
|
84
|
+
# SchemaComments::SchemaComment.count.should == 6
|
85
|
+
|
86
|
+
ActiveRecord::Migrator.up(migration_path, 5)
|
87
|
+
ActiveRecord::Migrator.current_version.should == 5
|
88
|
+
Product.columns.detect{|c| c.name == 'name'}.comment.should == '商品名'
|
89
|
+
|
90
|
+
ActiveRecord::Migrator.up(migration_path, 6)
|
91
|
+
ActiveRecord::Migrator.current_version.should == 6
|
92
|
+
Product.reset_column_comments
|
93
|
+
Product.columns.detect{|c| c.name == 'name'}.comment.should == '名称'
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
class CreateProducts < ActiveRecord::Migration
|
3
|
+
|
4
|
+
def self.up
|
5
|
+
create_table "products", :comment => '商品' do |t|
|
6
|
+
t.string "product_type_cd", :comment => '種別コード'
|
7
|
+
t.integer "price", :comment => "価格"
|
8
|
+
t.string "name", :comment => "商品名"
|
9
|
+
t.datetime "created_at", :comment => "登録日時"
|
10
|
+
t.datetime "updated_at", :comment => "更新日時"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.down
|
15
|
+
drop_table "products"
|
16
|
+
end
|
17
|
+
end
|