hobofields 0.8.5 → 0.8.6

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,5 +1,19 @@
1
1
  require 'echoe'
2
2
 
3
+ namespace "test" do
4
+ desc "Run the doctests"
5
+ task :doctest do |t|
6
+ exit(1) if !system("rubydoctest test/*.rdoctest")
7
+ end
8
+
9
+ desc "Run the unit tests"
10
+ task :unit do |t|
11
+ Dir["test/test_*.rb"].each do |f|
12
+ exit(1) if !system("ruby #{f}")
13
+ end
14
+ end
15
+ end
16
+
3
17
  Echoe.new('hobofields') do |p|
4
18
  p.author = "Tom Locke"
5
19
  p.email = "tom@tomlocke.com"
@@ -8,8 +22,9 @@ Echoe.new('hobofields') do |p|
8
22
  p.project = "hobo"
9
23
 
10
24
  p.changelog = "CHANGES.txt"
11
- p.version = "0.8.5"
25
+ p.version = "0.8.6"
12
26
 
13
- p.dependencies = ['hobosupport =0.8.5', 'rails >=2.2.2']
27
+ p.dependencies = ['hobosupport =0.8.6', 'rails >=2.2.2']
14
28
  p.development_dependencies = []
15
29
  end
30
+
data/hobofields.gemspec CHANGED
@@ -1,138 +1,38 @@
1
+ # -*- encoding: utf-8 -*-
1
2
 
2
- # Gem::Specification for Hobofields-0.8.5
3
- # Originally generated by Echoe
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{hobofields}
5
+ s.version = "0.8.6"
4
6
 
5
- --- !ruby/object:Gem::Specification
6
- name: hobofields
7
- version: !ruby/object:Gem::Version
8
- version: 0.8.5
9
- platform: ruby
10
- authors:
11
- - Tom Locke
12
- autorequire:
13
- bindir: bin
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Tom Locke"]
9
+ s.date = %q{2009-05-14}
10
+ s.description = %q{Rich field types and migration generator for Rails}
11
+ s.email = %q{tom@tomlocke.com}
12
+ s.extra_rdoc_files = ["lib/hobo_fields/email_address.rb", "lib/hobo_fields/enum_string.rb", "lib/hobo_fields/field_declaration_dsl.rb", "lib/hobo_fields/field_spec.rb", "lib/hobo_fields/fields_declaration.rb", "lib/hobo_fields/html_string.rb", "lib/hobo_fields/markdown_string.rb", "lib/hobo_fields/migration_generator.rb", "lib/hobo_fields/model_extensions.rb", "lib/hobo_fields/password_string.rb", "lib/hobo_fields/raw_html_string.rb", "lib/hobo_fields/raw_markdown_string.rb", "lib/hobo_fields/sanitize_html.rb", "lib/hobo_fields/serialized_object.rb", "lib/hobo_fields/text.rb", "lib/hobo_fields/textile_string.rb", "lib/hobo_fields.rb", "lib/hobofields.rb", "LICENSE.txt", "README.txt"]
13
+ s.files = ["CHANGES.txt", "init.rb", "lib/hobo_fields/email_address.rb", "lib/hobo_fields/enum_string.rb", "lib/hobo_fields/field_declaration_dsl.rb", "lib/hobo_fields/field_spec.rb", "lib/hobo_fields/fields_declaration.rb", "lib/hobo_fields/html_string.rb", "lib/hobo_fields/markdown_string.rb", "lib/hobo_fields/migration_generator.rb", "lib/hobo_fields/model_extensions.rb", "lib/hobo_fields/password_string.rb", "lib/hobo_fields/raw_html_string.rb", "lib/hobo_fields/raw_markdown_string.rb", "lib/hobo_fields/sanitize_html.rb", "lib/hobo_fields/serialized_object.rb", "lib/hobo_fields/text.rb", "lib/hobo_fields/textile_string.rb", "lib/hobo_fields.rb", "lib/hobofields.rb", "LICENSE.txt", "Manifest", "rails_generators/hobo_migration/hobo_migration_generator.rb", "rails_generators/hobo_migration/templates/migration.rb", "rails_generators/hobofield_model/hobofield_model_generator.rb", "rails_generators/hobofield_model/templates/fixtures.yml.erb", "rails_generators/hobofield_model/templates/model.rb.erb", "rails_generators/hobofield_model/templates/test.rb.erb", "rails_generators/hobofield_model/USAGE", "Rakefile", "README.txt", "script/destroy", "script/generate", "test/hobofields.rdoctest", "test/hobofields_api.rdoctest", "test/migration_generator.rdoctest", "test/rich_types.rdoctest", "test/test_generator_helper.rb", "test/test_hobofield_model_generator.rb", "hobofields.gemspec"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://hobocentral.net/hobofields}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Hobofields", "--main", "README.txt"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{hobo}
19
+ s.rubygems_version = %q{1.3.1}
20
+ s.summary = %q{Rich field types and migration generator for Rails}
21
+ s.test_files = ["test/test_generator_helper.rb", "test/test_hobofield_model_generator.rb"]
14
22
 
15
- date: 2008-12-09 00:00:00 +00:00
16
- default_executable:
17
- dependencies:
18
- - !ruby/object:Gem::Dependency
19
- name: hobosupport
20
- type: :runtime
21
- version_requirement:
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "="
25
- - !ruby/object:Gem::Version
26
- version: 0.8.5
27
- version:
28
- - !ruby/object:Gem::Dependency
29
- name: rails
30
- type: :runtime
31
- version_requirement:
32
- version_requirements: !ruby/object:Gem::Requirement
33
- requirements:
34
- - - ">="
35
- - !ruby/object:Gem::Version
36
- version: 2.2.2
37
- version:
38
- description: Rich field types and migration generator for Rails
39
- email: tom@tomlocke.com
40
- executables: []
23
+ if s.respond_to? :specification_version then
24
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
+ s.specification_version = 2
41
26
 
42
- extensions: []
43
-
44
- extra_rdoc_files:
45
- - lib/hobo_fields/email_address.rb
46
- - lib/hobo_fields/enum_string.rb
47
- - lib/hobo_fields/field_declaration_dsl.rb
48
- - lib/hobo_fields/field_spec.rb
49
- - lib/hobo_fields/fields_declaration.rb
50
- - lib/hobo_fields/html_string.rb
51
- - lib/hobo_fields/markdown_string.rb
52
- - lib/hobo_fields/migration_generator.rb
53
- - lib/hobo_fields/model_extensions.rb
54
- - lib/hobo_fields/password_string.rb
55
- - lib/hobo_fields/raw_html_string.rb
56
- - lib/hobo_fields/raw_markdown_string.rb
57
- - lib/hobo_fields/sanitize_html.rb
58
- - lib/hobo_fields/serialized_object.rb
59
- - lib/hobo_fields/text.rb
60
- - lib/hobo_fields/textile_string.rb
61
- - lib/hobo_fields.rb
62
- - lib/hobofields.rb
63
- - LICENSE.txt
64
- - README.txt
65
- files:
66
- - CHANGES.txt
67
- - init.rb
68
- - lib/hobo_fields/email_address.rb
69
- - lib/hobo_fields/enum_string.rb
70
- - lib/hobo_fields/field_declaration_dsl.rb
71
- - lib/hobo_fields/field_spec.rb
72
- - lib/hobo_fields/fields_declaration.rb
73
- - lib/hobo_fields/html_string.rb
74
- - lib/hobo_fields/markdown_string.rb
75
- - lib/hobo_fields/migration_generator.rb
76
- - lib/hobo_fields/model_extensions.rb
77
- - lib/hobo_fields/password_string.rb
78
- - lib/hobo_fields/raw_html_string.rb
79
- - lib/hobo_fields/raw_markdown_string.rb
80
- - lib/hobo_fields/sanitize_html.rb
81
- - lib/hobo_fields/serialized_object.rb
82
- - lib/hobo_fields/text.rb
83
- - lib/hobo_fields/textile_string.rb
84
- - lib/hobo_fields.rb
85
- - lib/hobofields.rb
86
- - LICENSE.txt
87
- - Manifest
88
- - rails_generators/hobo_migration/hobo_migration_generator.rb
89
- - rails_generators/hobo_migration/templates/migration.rb
90
- - rails_generators/hobofield_model/hobofield_model_generator.rb
91
- - rails_generators/hobofield_model/templates/fixtures.yml.erb
92
- - rails_generators/hobofield_model/templates/model.rb.erb
93
- - rails_generators/hobofield_model/templates/test.rb.erb
94
- - rails_generators/hobofield_model/USAGE
95
- - Rakefile
96
- - README.txt
97
- - script/destroy
98
- - script/generate
99
- - test/hobofields.rdoctest
100
- - test/hobofields_api.rdoctest
101
- - test/migration_generator.rdoctest
102
- - test/rich_types.rdoctest
103
- - test/test_generator_helper.rb
104
- - test/test_hobofield_model_generator.rb
105
- - hobofields.gemspec
106
- has_rdoc: true
107
- homepage: http://hobocentral.net/hobofields
108
- post_install_message:
109
- rdoc_options:
110
- - --line-numbers
111
- - --inline-source
112
- - --title
113
- - Hobofields
114
- - --main
115
- - README.txt
116
- require_paths:
117
- - lib
118
- required_ruby_version: !ruby/object:Gem::Requirement
119
- requirements:
120
- - - ">="
121
- - !ruby/object:Gem::Version
122
- version: "0"
123
- version:
124
- required_rubygems_version: !ruby/object:Gem::Requirement
125
- requirements:
126
- - - ">="
127
- - !ruby/object:Gem::Version
128
- version: "1.2"
129
- version:
130
- requirements: []
131
-
132
- rubyforge_project: hobo
133
- rubygems_version: 1.3.1
134
- specification_version: 2
135
- summary: Rich field types and migration generator for Rails
136
- test_files:
137
- - test/test_generator_helper.rb
138
- - test/test_hobofield_model_generator.rb
27
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
+ s.add_runtime_dependency(%q<hobosupport>, ["= 0.8.6"])
29
+ s.add_runtime_dependency(%q<rails>, [">= 2.2.2"])
30
+ else
31
+ s.add_dependency(%q<hobosupport>, ["= 0.8.6"])
32
+ s.add_dependency(%q<rails>, [">= 2.2.2"])
33
+ end
34
+ else
35
+ s.add_dependency(%q<hobosupport>, ["= 0.8.6"])
36
+ s.add_dependency(%q<rails>, [">= 2.2.2"])
37
+ end
38
+ end
@@ -13,7 +13,7 @@ module HoboFields
13
13
  end
14
14
 
15
15
  def to_html(xmldoctype = true)
16
- self
16
+ self.sub('@', " at ").gsub('.', ' dot ')
17
17
  end
18
18
 
19
19
  HoboFields.register_type(:email_address, self)
@@ -14,6 +14,8 @@ module HoboFields
14
14
  end
15
15
 
16
16
  attr_accessor :model, :name, :type, :position, :options
17
+
18
+ TYPE_SYNONYMS = [[:timestamp, :datetime]]
17
19
 
18
20
  def sql_type
19
21
  options[:sql_type] or begin
@@ -45,9 +47,20 @@ module HoboFields
45
47
  def default
46
48
  options[:default]
47
49
  end
50
+
51
+ def same_type?(col_spec)
52
+ t = sql_type
53
+ TYPE_SYNONYMS.each do |synonyms|
54
+ if t.in? synonyms
55
+ return col_spec.type.in?(synonyms)
56
+ end
57
+ end
58
+ t = col_spec.type
59
+ end
60
+
48
61
 
49
62
  def different_to?(col_spec)
50
- sql_type != col_spec.type ||
63
+ !same_type?(col_spec) ||
51
64
  begin
52
65
  check_attributes = [:null, :default]
53
66
  check_attributes += [:precision, :scale] if sql_type == :decimal
@@ -17,18 +17,14 @@ module HoboFields
17
17
  g.generate
18
18
  end
19
19
 
20
- def initialize(*args)
21
- options = args.extract_options!
22
- @ambiguity_resolver = args.first
20
+ def initialize(ambiguity_resolver={})
21
+ @ambiguity_resolver = ambiguity_resolver
23
22
  @drops = []
24
23
  @renames = nil
25
- @force_drop = options[:force_drop]
26
24
  end
27
25
 
28
26
  attr_accessor :renames
29
27
 
30
- def force_drop?; @force_drop end
31
-
32
28
 
33
29
  def load_rails_models
34
30
  if defined? RAILS_ROOT
@@ -80,11 +76,7 @@ module HoboFields
80
76
  # return a hash of table renames and modifies the passed arrays so
81
77
  # that renamed tables are no longer listed as to_create or to_drop
82
78
  def extract_table_renames!(to_create, to_drop)
83
- if force_drop?
84
- # no renames at all
85
- {}
86
-
87
- elsif renames
79
+ if renames
88
80
  # A hash of table renames has been provided
89
81
 
90
82
  to_rename = {}
@@ -110,11 +102,7 @@ module HoboFields
110
102
 
111
103
 
112
104
  def extract_column_renames!(to_add, to_remove, table_name)
113
- if force_drop?
114
- # no renames at all
115
- {}
116
-
117
- elsif renames
105
+ if renames
118
106
  to_rename = {}
119
107
  column_renames = renames._?[table_name.to_sym]
120
108
  if column_renames
@@ -150,8 +138,17 @@ module HoboFields
150
138
 
151
139
  def generate
152
140
  models, db_tables = models_and_tables
153
- models_by_table_name = models.index_by {|m| m.table_name}
154
- model_table_names = models.*.table_name
141
+ models_by_table_name = {}
142
+ models.each do |m|
143
+ if !models_by_table_name.has_key?(m.table_name)
144
+ models_by_table_name[m.table_name] = m
145
+ elsif m.superclass==models_by_table_name[m.table_name].superclass.superclass
146
+ # we need to ensure that models_by_table_name contains the
147
+ # base class in an STI hierarchy
148
+ models_by_table_name[m.table_name] = m
149
+ end
150
+ end
151
+ model_table_names = models_by_table_name.keys
155
152
 
156
153
  to_create = model_table_names - db_tables
157
154
  to_drop = db_tables - model_table_names - always_ignore_tables
@@ -200,7 +197,8 @@ module HoboFields
200
197
 
201
198
  def create_table(model)
202
199
  longest_field_name = model.field_specs.values.map { |f| f.sql_type.to_s.length }.max
203
- (["create_table :#{model.table_name} do |t|"] +
200
+ primary_key_option = ", :primary_key => :#{model.primary_key}" if model.primary_key != "id"
201
+ (["create_table :#{model.table_name}#{primary_key_option} do |t|"] +
204
202
  model.field_specs.values.sort_by{|f| f.position}.map {|f| create_field(f, longest_field_name)} +
205
203
  ["end"]) * "\n"
206
204
  end
@@ -213,15 +211,19 @@ module HoboFields
213
211
  def change_table(model, current_table_name)
214
212
  new_table_name = model.table_name
215
213
 
216
- db_columns = model.connection.columns(current_table_name).index_by{|c|c.name} - [model.primary_key]
214
+ db_columns = model.connection.columns(current_table_name).index_by{|c|c.name}
215
+ key_missing = db_columns[model.primary_key].nil?
216
+ db_columns -= [model.primary_key]
217
+
217
218
  model_column_names = model.field_specs.keys.*.to_s
218
219
  db_column_names = db_columns.keys.*.to_s
219
220
 
220
221
  to_add = model_column_names - db_column_names
222
+ to_add += [model.primary_key] if key_missing
221
223
  to_remove = db_column_names - model_column_names - [model.primary_key.to_sym]
222
224
 
223
225
  to_rename = extract_column_renames!(to_add, to_remove, new_table_name)
224
-
226
+
225
227
  db_column_names -= to_rename.keys
226
228
  db_column_names |= to_rename.values
227
229
  to_change = db_column_names & model_column_names
@@ -15,7 +15,6 @@ module HoboFields
15
15
  # and speeds things up a little.
16
16
  inheriting_cattr_reader :field_specs => HashWithIndifferentAccess.new
17
17
 
18
-
19
18
  def self.inherited(klass)
20
19
  fields do |f|
21
20
  f.field(inheritance_column, :string)
@@ -109,16 +108,16 @@ module HoboFields
109
108
  def self.declare_field(name, type, *args)
110
109
  options = args.extract_options!
111
110
  try.field_added(name, type, args, options)
112
- add_validations_for_field(name, type, args, options)
111
+ add_validations_for_field(name, type, args)
113
112
  declare_attr_type(name, type, options) unless HoboFields.plain_type?(type)
114
113
  field_specs[name] = FieldSpec.new(self, name, type, options)
115
114
  attr_order << name unless name.in?(attr_order)
116
115
  end
117
116
 
118
117
 
119
- # Add field validations according to arguments and options in the
118
+ # Add field validations according to arguments in the
120
119
  # field declaration
121
- def self.add_validations_for_field(name, type, args, options)
120
+ def self.add_validations_for_field(name, type, args)
122
121
  validates_presence_of name if :required.in?(args)
123
122
  validates_uniqueness_of name if :unique.in?(args)
124
123
 
data/lib/hobo_fields.rb CHANGED
@@ -9,7 +9,7 @@ end
9
9
 
10
10
  module HoboFields
11
11
 
12
- VERSION = "0.8.5"
12
+ VERSION = "0.8.6"
13
13
 
14
14
  extend self
15
15
 
@@ -18,13 +18,17 @@ module HoboFields
18
18
  :date => Date,
19
19
  :datetime => (defined?(ActiveSupport::TimeWithZone) ? ActiveSupport::TimeWithZone : Time),
20
20
  :time => Time,
21
- :integer => Fixnum,
22
- :big_integer => BigDecimal,
21
+ :integer => Integer,
23
22
  :decimal => BigDecimal,
24
23
  :float => Float,
25
24
  :string => String
26
25
  }
27
26
 
27
+ ALIAS_TYPES = {
28
+ Fixnum => "integer",
29
+ Bignum => "integer"
30
+ }
31
+
28
32
  # Provide a lookup for these rather than loading them all preemptively
29
33
 
30
34
  STANDARD_TYPES = {
@@ -44,7 +48,7 @@ module HoboFields
44
48
  attr_reader :field_types
45
49
 
46
50
  def to_class(type)
47
- if type.is_a?(Symbol, String)
51
+ if type.is_one_of?(Symbol, String)
48
52
  type = type.to_sym
49
53
  field_types[type] || standard_class(type)
50
54
  else
@@ -54,11 +58,13 @@ module HoboFields
54
58
 
55
59
 
56
60
  def to_name(type)
57
- field_types.index(type)
61
+ field_types.index(type) || ALIAS_TYPES[type]
58
62
  end
59
63
 
60
64
 
61
65
  def can_wrap?(type, val)
66
+ col_type = type::COLUMN_TYPE
67
+ return false if val.blank? && (col_type == :integer || col_type == :float || col_type == :decimal)
62
68
  klass = Object.instance_method(:class).bind(val).call # Make sure we get the *real* class
63
69
  arity = type.instance_method(:initialize).arity
64
70
  (arity == 1 || arity == -1) && !@never_wrap_types.any? { |c| klass <= c }
@@ -1,8 +1,6 @@
1
1
  require File.dirname(__FILE__) + '/../../lib/hobofields'
2
2
  class HoboMigrationGenerator < Rails::Generator::Base
3
3
 
4
- default_options :force_drop => false
5
-
6
4
  def initialize(runtime_args, runtime_options = {})
7
5
  super
8
6
  @migration_name = runtime_args.first || begin
@@ -29,7 +27,7 @@ class HoboMigrationGenerator < Rails::Generator::Base
29
27
  def manifest
30
28
  return record {|m| } if migrations_pending?
31
29
 
32
- generator = HoboFields::MigrationGenerator.new(self, :force_drop => options[:force_drop])
30
+ generator = HoboFields::MigrationGenerator.new(self)
33
31
  up, down = generator.generate
34
32
 
35
33
  if up.blank?
@@ -40,14 +38,14 @@ class HoboMigrationGenerator < Rails::Generator::Base
40
38
  puts "\n---------- Up Migration ----------", up, "----------------------------------"
41
39
  puts "\n---------- Down Migration --------", down, "----------------------------------"
42
40
 
43
- action = input("What now: [g]enerate migration, generate and [m]igrate now or [c]ancel?", /^(g|m|c)$/)
41
+ action = options[:action] || input("What now: [g]enerate migration, generate and [m]igrate now or [c]ancel?", /^(g|m|c)$/)
44
42
 
45
43
  if action == 'c'
46
44
  # record nothing to keep the generator happy
47
45
  record {|m| }
48
46
  else
49
47
  puts "\nMigration filename:", "(you can type spaces instead of '_' -- every little helps)"
50
- migration_name = input("Filename [#@migration_name]:", /^[a-z0-9_ ]*$/).strip.gsub(' ', '_')
48
+ migration_name = input("Filename [#@migration_name]:", /^[a-z0-9_ ]*$/).strip.gsub(' ', '_') unless options[:default_name]
51
49
  migration_name = @migration_name if migration_name.blank?
52
50
 
53
51
  at_exit { rake_migrate } if action == 'm'
@@ -68,6 +66,8 @@ class HoboMigrationGenerator < Rails::Generator::Base
68
66
 
69
67
 
70
68
  def extract_renames!(to_create, to_drop, kind_str, name_prefix="")
69
+ return {} if options[:force_drop]
70
+
71
71
  to_rename = {}
72
72
  rename_to_choices = to_create
73
73
  to_drop.dup.each do |t|
@@ -122,16 +122,17 @@ class HoboMigrationGenerator < Rails::Generator::Base
122
122
 
123
123
  protected
124
124
  def banner
125
- "Usage: #{$0} #{spec.name} [<migration-name>] [--force-drop]"
125
+ "Usage: #{$0} #{spec.name} [<migration-name>]"
126
126
  end
127
127
 
128
128
  def add_options!(opt)
129
129
  opt.separator ''
130
130
  opt.separator 'Options:'
131
- opt.on("--force-drop",
132
- "Don't prompt to disambiguate drops from renames - drop everything") do |v|
133
- options[:force_drop] = true
134
- end
131
+
132
+ opt.on("--force-drop", "Don't prompt with 'drop or rename' - just drop everything") { |v| options[:force_drop] = true }
133
+ opt.on("--default-name", "Dont' prompt for a migration name - just pick one") { |v| options[:default_name] = true }
134
+ opt.on("--generate", "Dont' prompt for action - generate the migration") { |v| options[:action] = 'g' }
135
+ opt.on("--migrate", "Dont' prompt for action - generate and migrate") { |v| options[:action] = 'm' }
135
136
  end
136
137
 
137
138
 
@@ -14,7 +14,7 @@ It still has all the benefits of writing your own migrations, for example if you
14
14
 
15
15
  First off, if you're using the migration generator outside of Hobo, do remember the `--skip-migration` option when generating your models:
16
16
 
17
- $ ./script/generate model blog_post --skip-migration
17
+ $ ./script/generate model blog_post --skip-migration
18
18
 
19
19
  Now edit your model as follows:
20
20
 
@@ -30,22 +30,22 @@ Now edit your model as follows:
30
30
 
31
31
  Then, simply run
32
32
 
33
- $ ./script/genearte hobo_migration
33
+ $ ./script/genearte hobo_migration
34
34
 
35
35
  And voila
36
36
 
37
- ---------- Up Migration ----------
38
- create_table :blog_posts do |t|
39
- t.string :title
40
- t.text :body
41
- t.datetime :created_at
42
- t.datetime :updated_at
43
- end
44
- ----------------------------------
45
-
46
- ---------- Down Migration --------
47
- drop_table :blog_posts
48
- ----------------------------------
37
+ ---------- Up Migration ----------
38
+ create_table :blog_posts do |t|
39
+ t.string :title
40
+ t.text :body
41
+ t.datetime :created_at
42
+ t.datetime :updated_at
43
+ end
44
+ ----------------------------------
45
+
46
+ ---------- Down Migration --------
47
+ drop_table :blog_posts
48
+ ----------------------------------
49
49
  {: .ruby}
50
50
 
51
51
  The migration generator has created a migration to change from the schema that is currently in your database, to the schema that your models need. That's really all there is to it. You are now free to simply hack away on your app and run the migration generator every time the database needs to play catch-up.
@@ -54,9 +54,9 @@ Note that the migration generator is interactive -- it can't tell the difference
54
54
 
55
55
  ## Installing
56
56
 
57
- The simplest and recommended way to install HoboFeilds is as a gem:
57
+ The simplest and recommended way to install HoboFields is as a gem:
58
58
 
59
- $ gem install hobofields
59
+ $ gem install hobofields
60
60
 
61
61
  The source lives on GitHub as part of the main Hobo repo:
62
62
 
@@ -64,7 +64,7 @@ The source lives on GitHub as part of the main Hobo repo:
64
64
 
65
65
  The simplest way to install HoboFields as a plugin is to use the subversion mirror:
66
66
 
67
- svn export svn://hobocentral.net/hobo/tags/rel_0.7.5/hobofields vendor/plugins
67
+ svn export svn://hobocentral.net/hobo/tags/rel_0.7.5/hobofields vendor/plugins
68
68
 
69
69
  ## Rich Types
70
70
 
@@ -72,19 +72,19 @@ In addition to the migration generator, HoboFields provides a Rich-Type mechanis
72
72
 
73
73
  Read more:
74
74
 
75
- - [HoboFields Rich Types](/hobofields/rich_types)
75
+ - [HoboFields Rich Types](/manual/hobofields/rich_types)
76
76
 
77
77
  ## API
78
78
 
79
79
  HoboFields provides various API methods. Read more:
80
80
 
81
- - [HoboFields API](/hobofields/hobofields_api)
81
+ - [HoboFields API](/manual/hobofields/hobofields_api)
82
82
 
83
83
  ## Migration Generator Details
84
84
 
85
85
  The migration generator doctests provide a lot more detail. They're not really that great as documentation because doctests run in a single irb session, and that doesn't fit well with the concept of a generator. Skip these unless you're really keen to see the details of the migration generator in action
86
86
 
87
- - [Migration Generator Details](/hobofields/migration_generator)
87
+ - [Migration Generator Details](/manual/hobofields/migration_generator)
88
88
 
89
89
  ## About Doctests
90
90
 
@@ -92,3 +92,5 @@ HoboFields is documented and tested using *doctests*. This is an idea that comes
92
92
 
93
93
  Doctests are a great way to get both documentation and tests from the same source. We're still experimenting with exactly how this all works though, so if the docs seem strange in places, please bear with us!
94
94
 
95
+ You may download rubydoctest via [github](http://www.github.com/tablatom/rubydoctest)
96
+