hobo 0.7.2 → 0.7.3

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.
Files changed (77) hide show
  1. data/bin/hobo +24 -7
  2. data/hobo_files/plugin/CHANGES.txt +501 -0
  3. data/hobo_files/plugin/generators/hobo/hobo_generator.rb +8 -6
  4. data/hobo_files/plugin/generators/hobo/templates/application.dryml +3 -0
  5. data/hobo_files/plugin/generators/hobo/templates/dryml-support.js +132 -0
  6. data/hobo_files/plugin/generators/hobo_front_controller/hobo_front_controller_generator.rb +4 -5
  7. data/hobo_files/plugin/generators/hobo_model_resource/hobo_model_resource_generator.rb +75 -0
  8. data/hobo_files/plugin/generators/hobo_model_resource/templates/controller.rb +7 -0
  9. data/hobo_files/plugin/generators/hobo_model_resource/templates/functional_test.rb +8 -0
  10. data/hobo_files/plugin/generators/hobo_model_resource/templates/helper.rb +2 -0
  11. data/hobo_files/plugin/generators/hobo_rapid/templates/hobo-rapid.js +30 -11
  12. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/application.css +149 -92
  13. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/rapid-ui.css +0 -48
  14. data/hobo_files/plugin/init.rb +45 -13
  15. data/hobo_files/plugin/lib/action_view_extensions/base.rb +4 -3
  16. data/hobo_files/plugin/lib/active_record/association_proxy.rb +18 -0
  17. data/hobo_files/plugin/lib/active_record/association_reflection.rb +5 -0
  18. data/hobo_files/plugin/lib/active_record/has_many_association.rb +7 -11
  19. data/hobo_files/plugin/lib/active_record/has_many_through_association.rb +8 -0
  20. data/hobo_files/plugin/lib/extensions/test_case.rb +1 -1
  21. data/hobo_files/plugin/lib/hobo.rb +38 -60
  22. data/hobo_files/plugin/lib/hobo/authentication_support.rb +1 -1
  23. data/hobo_files/plugin/lib/hobo/bundle.rb +131 -34
  24. data/hobo_files/plugin/lib/hobo/composite_model.rb +1 -1
  25. data/hobo_files/plugin/lib/hobo/controller.rb +7 -8
  26. data/hobo_files/plugin/lib/hobo/dev_controller.rb +21 -0
  27. data/hobo_files/plugin/lib/hobo/dryml/dryml_builder.rb +14 -8
  28. data/hobo_files/plugin/lib/hobo/dryml/dryml_support_controller.rb +13 -0
  29. data/hobo_files/plugin/lib/hobo/dryml/taglib.rb +6 -7
  30. data/hobo_files/plugin/lib/hobo/dryml/template.rb +207 -73
  31. data/hobo_files/plugin/lib/hobo/dryml/template_environment.rb +67 -55
  32. data/hobo_files/plugin/lib/hobo/dryml/template_handler.rb +53 -3
  33. data/hobo_files/plugin/lib/hobo/hobo_helper.rb +75 -107
  34. data/hobo_files/plugin/lib/hobo/model.rb +236 -429
  35. data/hobo_files/plugin/lib/hobo/model_controller.rb +277 -437
  36. data/hobo_files/plugin/lib/hobo/model_router.rb +62 -29
  37. data/hobo_files/plugin/lib/hobo/rapid_helper.rb +48 -9
  38. data/hobo_files/plugin/lib/hobo/scopes.rb +98 -0
  39. data/hobo_files/plugin/lib/hobo/scopes/association_proxy_extensions.rb +31 -0
  40. data/hobo_files/plugin/lib/hobo/scopes/automatic_scopes.rb +282 -0
  41. data/hobo_files/plugin/lib/hobo/scopes/defined_scope_proxy_extender.rb +88 -0
  42. data/hobo_files/plugin/lib/hobo/scopes/scope_reflection.rb +18 -0
  43. data/hobo_files/plugin/lib/hobo/scopes/scoped_proxy.rb +59 -0
  44. data/hobo_files/plugin/lib/hobo/undefined.rb +2 -0
  45. data/hobo_files/plugin/lib/hobo/user.rb +31 -14
  46. data/hobo_files/plugin/lib/hobo/user_controller.rb +41 -27
  47. data/hobo_files/plugin/taglibs/core.dryml +9 -11
  48. data/hobo_files/plugin/taglibs/rapid.dryml +51 -108
  49. data/hobo_files/plugin/taglibs/rapid_editing.dryml +25 -25
  50. data/hobo_files/plugin/taglibs/rapid_forms.dryml +111 -79
  51. data/hobo_files/plugin/taglibs/rapid_generics.dryml +74 -0
  52. data/hobo_files/plugin/taglibs/rapid_navigation.dryml +23 -21
  53. data/hobo_files/plugin/taglibs/rapid_pages.dryml +83 -169
  54. data/hobo_files/plugin/taglibs/rapid_plus.dryml +16 -2
  55. data/hobo_files/plugin/taglibs/rapid_support.dryml +3 -3
  56. data/hobo_files/plugin/taglibs/rapid_user_pages.dryml +104 -0
  57. metadata +60 -55
  58. data/hobo_files/plugin/generators/hobo_migration/hobo_migration_generator.rb +0 -276
  59. data/hobo_files/plugin/generators/hobo_migration/templates/migration.rb +0 -9
  60. data/hobo_files/plugin/lib/active_record/table_definition.rb +0 -34
  61. data/hobo_files/plugin/lib/extensions.rb +0 -375
  62. data/hobo_files/plugin/lib/hobo/email_address.rb +0 -12
  63. data/hobo_files/plugin/lib/hobo/enum_string.rb +0 -50
  64. data/hobo_files/plugin/lib/hobo/field_declaration_dsl.rb +0 -43
  65. data/hobo_files/plugin/lib/hobo/field_spec.rb +0 -68
  66. data/hobo_files/plugin/lib/hobo/html_string.rb +0 -7
  67. data/hobo_files/plugin/lib/hobo/lazy_hash.rb +0 -40
  68. data/hobo_files/plugin/lib/hobo/markdown_string.rb +0 -11
  69. data/hobo_files/plugin/lib/hobo/migrations.rb +0 -12
  70. data/hobo_files/plugin/lib/hobo/model_queries.rb +0 -117
  71. data/hobo_files/plugin/lib/hobo/password_string.rb +0 -7
  72. data/hobo_files/plugin/lib/hobo/percentage.rb +0 -14
  73. data/hobo_files/plugin/lib/hobo/predicate_dispatch.rb +0 -78
  74. data/hobo_files/plugin/lib/hobo/proc_binding.rb +0 -32
  75. data/hobo_files/plugin/lib/hobo/text.rb +0 -3
  76. data/hobo_files/plugin/lib/hobo/textile_string.rb +0 -25
  77. data/hobo_files/plugin/lib/hobo/where_fragment.rb +0 -28
@@ -5,8 +5,8 @@
5
5
  <div class="search">
6
6
  <form param="search-form" method="get" action="">
7
7
  <hidden-fields for-query-string skip="page, search_form"/>
8
- Search
9
- <input class="search-field" type="search" name="search" value="&params[:search]"/>
8
+ <span>Search</span>
9
+ <input class="search" type="search" name="search" value="&params[:search]"/>
10
10
  <submit label="Go" class="search-button" param="search-submit"/>
11
11
  </form>
12
12
  </div>
@@ -41,3 +41,17 @@
41
41
  </nav>
42
42
  </div>
43
43
  </def>
44
+
45
+
46
+ <def tag="change-password-form">
47
+ <form class="change-password" param>
48
+ <field-list fields="current_password, password, password_confirmation" param>
49
+ <password-label:>New Password</password-label:>
50
+ <password-confirmation-label:>Confirm New Password</password-confirmation-label:>
51
+ </field-list>
52
+
53
+ <div class="actions" param="actions">
54
+ <submit label="Change Password" param/>
55
+ </div>
56
+ </form>
57
+ </def>
@@ -4,7 +4,7 @@
4
4
 
5
5
  elsif fields.nil? || fields == "*" || fields.is_a?(Class)
6
6
  klass = fields.is_a?(Class) ? fields : this.class
7
- columns = klass.content_columns.every(:name)
7
+ columns = klass.content_columns.*.name
8
8
  columns -= %w{created_at updated_at created_on updated_on} unless
9
9
  include_timestamps
10
10
 
@@ -27,8 +27,8 @@
27
27
 
28
28
  <def tag="with-field-names" attrs="fields, skip, skip-associations, include-timestamps"><%=
29
29
  field_names = if fields.nil? || fields == "*" || fields.is_a?(Class)
30
- klass = fields.is_a?(Class) ? fields : this.proxy_reflectin.class
31
- columns = klass.content_columns.every(:name)
30
+ klass = fields.is_a?(Class) ? fields : this.member_class
31
+ columns = klass.content_columns.*.name
32
32
  columns -= %w{created_at updated_at created_on updated_on} unless include_timestamps
33
33
 
34
34
  if skip_associations == "has_many"
@@ -0,0 +1,104 @@
1
+ <def tag="signup-page">
2
+ <page layout="simple" title="Sign up to #{app_name}" merge>
3
+ <body: class="signup-page" param/>
4
+
5
+ <live-search: replace/>
6
+ <nav: replace/>
7
+
8
+ <content-header: param>
9
+ <heading param>Sign Up</heading>
10
+ </content-header>
11
+
12
+ <content-body: param>
13
+ <error-messages/>
14
+ <form action="&request.request_uri" param>
15
+ <field-list fields="login, password, password_confirmation" param>
16
+ <login-label:><%= model.login_attribute.to_s.titleize %></login-label>
17
+ <password-confirmation-label:>Confirm Password</password-confirmation-label>
18
+ </field-list>
19
+
20
+ <div class="actions" param="actions">
21
+ <submit label='Sign Up'/>
22
+ </div>
23
+ </form>
24
+ </content-body>
25
+
26
+ </page>
27
+ </def>
28
+
29
+
30
+ <def tag="login-page" attrs="remember-me">
31
+ <page layout="simple" title="Log in to #{app_name}" merge>
32
+
33
+ <body: class="login-page" param/>
34
+
35
+ <live-search: replace/>
36
+ <nav: replace/>
37
+
38
+ <content-header: param>
39
+ <heading param>Log In</heading>
40
+ </content-header>
41
+
42
+ <content-body: param>
43
+ <form action="&request.request_uri" class="login" param>
44
+ <labelled-item-list param>
45
+ <labelled-item>
46
+ <item-label param="login-label"><%= model.login_attribute.to_s.titleize %></item-label>
47
+ <item-value><input type="text" name="login" id="login" class="string" param="login-input" /></item-value>
48
+ </labelled-item>
49
+
50
+ <labelled-item>
51
+ <item-label param="password-label">Password</item-label>
52
+ <item-value><input type="password" name="password" id="password" class="string" param="password-input"/></item-value>
53
+ </labelled-item>
54
+
55
+ <labelled-item if="&remember_me">
56
+ <item-label class="field-label" param="remember-me-label">Remember me:</item-label>
57
+ <item-value><input type="checkbox" name="remember_me" id="remember-me" param="remember-me-input"/></item-value>
58
+ </labelled-item>
59
+ </labelled-item-list>
60
+ <set user="&Hobo::User.default_user_model"/>
61
+ <div class="actions" param="actions">
62
+ <submit label='Log in' param/><if test="&signup_url(user)" class='nav-item'> or <a href="&signup_url(user)">Sign up</a></if>
63
+ </div>
64
+ </form>
65
+ </content-body>
66
+ </page>
67
+ </def>
68
+
69
+
70
+ <def tag="account-disabled-page">
71
+
72
+ <page layout="simple" title="#{app_name} - account not available" merge>
73
+
74
+ <body: class="account-disabled-page" param/>
75
+
76
+ <content-header: param><heading param>Account is not available</heading></content>
77
+
78
+ <content-body: param>
79
+ <p>Your account is not available at this time.</p>
80
+ </content-body>
81
+ </page>
82
+
83
+ </def>
84
+
85
+
86
+ <def tag="account-page">
87
+
88
+ <page title="#{name} - Account" merge>
89
+
90
+ <body: class="user-account-page #{type_name}" param/>
91
+
92
+ <content-header: param>
93
+ <heading><name/></heading>
94
+ </content-header:>
95
+
96
+ <content-body: param>
97
+ <error-messages param/>
98
+ <h2>Change Password</h2>
99
+ <change-password-form/>
100
+ </content-body:>
101
+
102
+ </page>
103
+
104
+ </def>
metadata CHANGED
@@ -1,33 +1,26 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.4
3
- specification_version: 1
4
2
  name: hobo
5
3
  version: !ruby/object:Gem::Version
6
- version: 0.7.2
7
- date: 2008-01-04 00:00:00 +00:00
8
- summary: The web app builder for Rails
9
- require_paths:
10
- - lib
11
- email: tom@hobocentral.net
12
- homepage: http://hobocentral.net
13
- rubyforge_project:
14
- description:
15
- autorequire:
16
- default_executable:
17
- bindir: bin
18
- has_rdoc: false
19
- required_ruby_version: !ruby/object:Gem::Version::Requirement
20
- requirements:
21
- - - ">"
22
- - !ruby/object:Gem::Version
23
- version: 0.0.0
24
- version:
4
+ version: 0.7.3
25
5
  platform: ruby
26
- signing_key:
27
- cert_chain:
28
- post_install_message:
29
6
  authors:
30
7
  - Tom Locke
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-03-14 00:00:00 +00:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: tom@hobocentral.net
18
+ executables:
19
+ - hobo
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
31
24
  files:
32
25
  - hobo_files/plugin
33
26
  - hobo_files/plugin/CHANGES.txt
@@ -36,6 +29,7 @@ files:
36
29
  - hobo_files/plugin/generators/hobo/hobo_generator.rb
37
30
  - hobo_files/plugin/generators/hobo/templates
38
31
  - hobo_files/plugin/generators/hobo/templates/application.dryml
32
+ - hobo_files/plugin/generators/hobo/templates/dryml-support.js
39
33
  - hobo_files/plugin/generators/hobo/templates/guest.rb
40
34
  - hobo_files/plugin/generators/hobo_front_controller
41
35
  - hobo_files/plugin/generators/hobo_front_controller/hobo_front_controller_generator.rb
@@ -46,10 +40,6 @@ files:
46
40
  - hobo_files/plugin/generators/hobo_front_controller/templates/index.dryml
47
41
  - hobo_files/plugin/generators/hobo_front_controller/templates/search.dryml
48
42
  - hobo_files/plugin/generators/hobo_front_controller/USAGE
49
- - hobo_files/plugin/generators/hobo_migration
50
- - hobo_files/plugin/generators/hobo_migration/hobo_migration_generator.rb
51
- - hobo_files/plugin/generators/hobo_migration/templates
52
- - hobo_files/plugin/generators/hobo_migration/templates/migration.rb
53
43
  - hobo_files/plugin/generators/hobo_model
54
44
  - hobo_files/plugin/generators/hobo_model/hobo_model_generator.rb
55
45
  - hobo_files/plugin/generators/hobo_model/templates
@@ -64,6 +54,12 @@ files:
64
54
  - hobo_files/plugin/generators/hobo_model_controller/templates/functional_test.rb
65
55
  - hobo_files/plugin/generators/hobo_model_controller/templates/helper.rb
66
56
  - hobo_files/plugin/generators/hobo_model_controller/USAGE
57
+ - hobo_files/plugin/generators/hobo_model_resource
58
+ - hobo_files/plugin/generators/hobo_model_resource/hobo_model_resource_generator.rb
59
+ - hobo_files/plugin/generators/hobo_model_resource/templates
60
+ - hobo_files/plugin/generators/hobo_model_resource/templates/controller.rb
61
+ - hobo_files/plugin/generators/hobo_model_resource/templates/functional_test.rb
62
+ - hobo_files/plugin/generators/hobo_model_resource/templates/helper.rb
67
63
  - hobo_files/plugin/generators/hobo_rapid
68
64
  - hobo_files/plugin/generators/hobo_rapid/hobo_rapid_generator.rb
69
65
  - hobo_files/plugin/generators/hobo_rapid/templates
@@ -140,19 +136,21 @@ files:
140
136
  - hobo_files/plugin/lib/action_view_extensions
141
137
  - hobo_files/plugin/lib/action_view_extensions/base.rb
142
138
  - hobo_files/plugin/lib/active_record
139
+ - hobo_files/plugin/lib/active_record/association_proxy.rb
140
+ - hobo_files/plugin/lib/active_record/association_reflection.rb
143
141
  - hobo_files/plugin/lib/active_record/has_many_association.rb
144
142
  - hobo_files/plugin/lib/active_record/has_many_through_association.rb
145
- - hobo_files/plugin/lib/active_record/table_definition.rb
146
143
  - hobo_files/plugin/lib/extensions
147
144
  - hobo_files/plugin/lib/extensions/test_case.rb
148
- - hobo_files/plugin/lib/extensions.rb
149
145
  - hobo_files/plugin/lib/hobo
150
146
  - hobo_files/plugin/lib/hobo/authentication_support.rb
151
147
  - hobo_files/plugin/lib/hobo/bundle.rb
152
148
  - hobo_files/plugin/lib/hobo/composite_model.rb
153
149
  - hobo_files/plugin/lib/hobo/controller.rb
150
+ - hobo_files/plugin/lib/hobo/dev_controller.rb
154
151
  - hobo_files/plugin/lib/hobo/dryml
155
152
  - hobo_files/plugin/lib/hobo/dryml/dryml_builder.rb
153
+ - hobo_files/plugin/lib/hobo/dryml/dryml_support_controller.rb
156
154
  - hobo_files/plugin/lib/hobo/dryml/part_context.rb
157
155
  - hobo_files/plugin/lib/hobo/dryml/scoped_variables.rb
158
156
  - hobo_files/plugin/lib/hobo/dryml/tag_parameters.rb
@@ -161,35 +159,26 @@ files:
161
159
  - hobo_files/plugin/lib/hobo/dryml/template_environment.rb
162
160
  - hobo_files/plugin/lib/hobo/dryml/template_handler.rb
163
161
  - hobo_files/plugin/lib/hobo/dryml.rb
164
- - hobo_files/plugin/lib/hobo/email_address.rb
165
- - hobo_files/plugin/lib/hobo/enum_string.rb
166
- - hobo_files/plugin/lib/hobo/field_declaration_dsl.rb
167
- - hobo_files/plugin/lib/hobo/field_spec.rb
168
162
  - hobo_files/plugin/lib/hobo/generator.rb
169
163
  - hobo_files/plugin/lib/hobo/guest.rb
170
164
  - hobo_files/plugin/lib/hobo/hobo_helper.rb
171
- - hobo_files/plugin/lib/hobo/html_string.rb
172
- - hobo_files/plugin/lib/hobo/lazy_hash.rb
173
- - hobo_files/plugin/lib/hobo/markdown_string.rb
174
- - hobo_files/plugin/lib/hobo/migrations.rb
175
165
  - hobo_files/plugin/lib/hobo/model.rb
176
166
  - hobo_files/plugin/lib/hobo/model_controller.rb
177
- - hobo_files/plugin/lib/hobo/model_queries.rb
178
167
  - hobo_files/plugin/lib/hobo/model_router.rb
179
168
  - hobo_files/plugin/lib/hobo/model_support.rb
180
- - hobo_files/plugin/lib/hobo/password_string.rb
181
- - hobo_files/plugin/lib/hobo/percentage.rb
182
- - hobo_files/plugin/lib/hobo/predicate_dispatch.rb
183
- - hobo_files/plugin/lib/hobo/proc_binding.rb
184
169
  - hobo_files/plugin/lib/hobo/rapid_helper.rb
170
+ - hobo_files/plugin/lib/hobo/scopes
171
+ - hobo_files/plugin/lib/hobo/scopes/association_proxy_extensions.rb
172
+ - hobo_files/plugin/lib/hobo/scopes/automatic_scopes.rb
173
+ - hobo_files/plugin/lib/hobo/scopes/defined_scope_proxy_extender.rb
174
+ - hobo_files/plugin/lib/hobo/scopes/scope_reflection.rb
175
+ - hobo_files/plugin/lib/hobo/scopes/scoped_proxy.rb
176
+ - hobo_files/plugin/lib/hobo/scopes.rb
185
177
  - hobo_files/plugin/lib/hobo/static_tags
186
- - hobo_files/plugin/lib/hobo/text.rb
187
- - hobo_files/plugin/lib/hobo/textile_string.rb
188
178
  - hobo_files/plugin/lib/hobo/undefined.rb
189
179
  - hobo_files/plugin/lib/hobo/undefined_access_error.rb
190
180
  - hobo_files/plugin/lib/hobo/user.rb
191
181
  - hobo_files/plugin/lib/hobo/user_controller.rb
192
- - hobo_files/plugin/lib/hobo/where_fragment.rb
193
182
  - hobo_files/plugin/lib/hobo.rb
194
183
  - hobo_files/plugin/lib/rexml.rb
195
184
  - hobo_files/plugin/LICENSE.txt
@@ -201,10 +190,12 @@ files:
201
190
  - hobo_files/plugin/taglibs/rapid_document_tags.dryml
202
191
  - hobo_files/plugin/taglibs/rapid_editing.dryml
203
192
  - hobo_files/plugin/taglibs/rapid_forms.dryml
193
+ - hobo_files/plugin/taglibs/rapid_generics.dryml
204
194
  - hobo_files/plugin/taglibs/rapid_navigation.dryml
205
195
  - hobo_files/plugin/taglibs/rapid_pages.dryml
206
196
  - hobo_files/plugin/taglibs/rapid_plus.dryml
207
197
  - hobo_files/plugin/taglibs/rapid_support.dryml
198
+ - hobo_files/plugin/taglibs/rapid_user_pages.dryml
208
199
  - hobo_files/plugin/tasks
209
200
  - hobo_files/plugin/tasks/dump_fixtures.rake
210
201
  - hobo_files/plugin/tasks/environments.rake
@@ -214,17 +205,31 @@ files:
214
205
  - bin/hobo
215
206
  - LICENSE.txt
216
207
  - README.txt
217
- test_files: []
218
-
208
+ has_rdoc: false
209
+ homepage: http://hobocentral.net
210
+ post_install_message:
219
211
  rdoc_options: []
220
212
 
221
- extra_rdoc_files: []
222
-
223
- executables:
224
- - hobo
225
- extensions: []
226
-
213
+ require_paths:
214
+ - lib
215
+ required_ruby_version: !ruby/object:Gem::Requirement
216
+ requirements:
217
+ - - ">="
218
+ - !ruby/object:Gem::Version
219
+ version: "0"
220
+ version:
221
+ required_rubygems_version: !ruby/object:Gem::Requirement
222
+ requirements:
223
+ - - ">="
224
+ - !ruby/object:Gem::Version
225
+ version: "0"
226
+ version:
227
227
  requirements: []
228
228
 
229
- dependencies: []
229
+ rubyforge_project:
230
+ rubygems_version: 1.0.1
231
+ signing_key:
232
+ specification_version: 2
233
+ summary: The web app builder for Rails
234
+ test_files: []
230
235
 
@@ -1,276 +0,0 @@
1
- class HoboMigrationGenerator < Rails::Generator::Base
2
-
3
- def initialize(runtime_args, runtime_options = {})
4
- super
5
- @migration_name = runtime_args.first || begin
6
- i = Dir["#{RAILS_ROOT}/db/migrate/*hobo_migration*"].length
7
- "hobo_migration_#{i+1}"
8
- end
9
- end
10
-
11
- def table_model_classes
12
- ActiveRecord::Base.send(:subclasses).
13
- reject {|c| c.name.starts_with?("CGI::") }.
14
- select {|c| c.superclass == ActiveRecord::Base}
15
- end
16
-
17
- def manifest
18
- connection = ActiveRecord::Base.connection
19
- @types = connection.native_database_types
20
-
21
- # Force load of hobo models
22
- Hobo.models
23
-
24
- ignore_model_names = Hobo::Migrations.ignore.every(:underscore)
25
-
26
- models, ignore_models = table_model_classes.partition do |m|
27
- m.name.underscore.not_in?(ignore_model_names) && m < Hobo::Model
28
- end
29
- ignore_tables = ignore_models.every(:table_name) | Hobo::Migrations.ignore_tables
30
-
31
- models_by_table_name = models.index_by {|m| m.table_name}
32
- model_table_names = models.every(:table_name)
33
- db_tables = connection.tables - ignore_tables
34
-
35
- to_create = model_table_names - db_tables
36
- to_drop = db_tables - model_table_names - ['schema_info']
37
- to_change = model_table_names
38
-
39
- to_rename = rename_or_drop!(to_create, to_drop, "table")
40
-
41
- renames = to_rename.map do |old_name, new_name|
42
- "rename_table :#{old_name}, :#{new_name}"
43
- end * "\n"
44
- undo_renames = to_rename.map do |old_name, new_name|
45
- "rename_table :#{new_name}, :#{old_name}"
46
- end * "\n"
47
-
48
- drops = to_drop.map do |t|
49
- "drop_table :#{t}"
50
- end * "\n"
51
- undo_drops = to_drop.map do |t|
52
- revert_table(t)
53
- end * "\n\n"
54
-
55
- creates = to_create.map do |t|
56
- create_table(models_by_table_name[t])
57
- end * "\n\n"
58
- undo_creates = to_create.map do |t|
59
- "drop_table :#{t}"
60
- end * "\n"
61
-
62
- changes = []
63
- undo_changes = []
64
- to_change.each do |t|
65
- model = models_by_table_name[t]
66
- table = to_rename.index(t) || model.table_name
67
- if table.in?(db_tables)
68
- change, undo = change_table(model, table)
69
- changes << change
70
- undo_changes << undo
71
- end
72
- end
73
-
74
- up = [renames, drops, creates, changes].flatten.reject(&:blank?) * "\n\n"
75
- down = [undo_changes, undo_renames, undo_drops, undo_creates].flatten.reject(&:blank?) * "\n\n"
76
-
77
- if up.blank?
78
- puts "Database and models match -- nothing to change"
79
- return record {|m| }
80
- end
81
-
82
- puts "\n---------- Up Migration ----------", up, "----------------------------------"
83
- puts "\n---------- Down Migration --------", down, "----------------------------------"
84
-
85
- action = input("What now: [g]enerate migration, generate and [m]igrate now or [c]ancel?", %w(g m c))
86
-
87
- if action == 'c'
88
- # record nothing to keep the generator happy
89
- record {|m| }
90
- else
91
- puts "\nMigration filename:", "(you can type spaces instead of '_' -- every little helps)"
92
- migration_name = input("Filename [#@migration_name]:").strip.gsub(' ', '_')
93
- migration_name = @migration_name if migration_name.blank?
94
-
95
- at_exit { system "rake db:migrate" } if action == 'm'
96
-
97
- up.gsub!("\n", "\n ")
98
- down.gsub!("\n", "\n ")
99
-
100
- record do |m|
101
- m.migration_template 'migration.rb', 'db/migrate',
102
- :assigns => { :up => up, :down => down, :migration_name => migration_name.camelize },
103
- :migration_file_name => migration_name
104
- end
105
- end
106
- rescue Hobo::FieldSpec::UnknownSqlTypeError => e
107
- puts "Invalid field type '#{e.message[2]}' for #{e.message[0]}.#{e.message[1]}"
108
- record {|m| }
109
- end
110
-
111
- def rename_or_drop!(to_create, to_drop, kind_str, name_prefix="")
112
- to_rename = {}
113
- rename_to_choices = to_create
114
- to_drop.dup.each do |t|
115
- if rename_to_choices.empty?
116
- puts "\nCONFIRM DROP! #{kind_str} #{name_prefix}#{t}"
117
- resp = input("Enter 'drop #{t}' to confirm:")
118
- if resp.strip != "drop " + t.to_s
119
- to_drop.delete(t)
120
- end
121
- else
122
- puts "\nDROP or RENAME?: #{kind_str} #{name_prefix}#{t}"
123
- puts "Rename choices: #{to_create * ', '}"
124
- resp = input("Enter either 'drop #{t}' or one of the rename choices:")
125
- resp.strip!
126
-
127
- if resp == "drop " + t
128
- # Leave things as they are
129
- else
130
- to_drop.delete(t)
131
- if resp.in?(rename_to_choices)
132
- to_rename[t] = resp
133
- to_create.delete(resp)
134
- rename_to_choices.delete(resp)
135
- end
136
- end
137
- end
138
- end
139
- to_rename
140
- end
141
-
142
- def create_table(model)
143
- longest_field_name = model.field_specs.values.map { |f| f.sql_type.to_s.length }.max
144
- (["create_table :#{model.table_name} do |t|"] +
145
- model.field_specs.values.sort_by{|f| f.position}.map {|f| create_field(f, longest_field_name)} +
146
- ["end"]) * "\n"
147
- end
148
-
149
- def create_field(field_spec, field_name_width)
150
- args = [field_spec.name.inspect] + format_options(field_spec.options, field_spec.sql_type)
151
- " t.%-*s %s" % [field_name_width, field_spec.sql_type, args.join(', ')]
152
- end
153
-
154
- def change_table(model, current_table_name)
155
- new_table_name = model.table_name
156
-
157
- db_columns = model.connection.columns(current_table_name).index_by{|c|c.name} - [model.primary_key]
158
- model_column_names = model.field_specs.keys.every(:to_s)
159
- db_column_names = db_columns.keys.every(:to_s)
160
-
161
- to_add = model_column_names - db_column_names
162
- to_remove = db_column_names - model_column_names - [model.primary_key.to_sym]
163
-
164
- to_rename = rename_or_drop!(to_add, to_remove, "column", "#{new_table_name}.")
165
-
166
- db_column_names -= to_rename.keys
167
- db_column_names |= to_rename.values
168
- to_change = db_column_names & model_column_names
169
-
170
- renames = to_rename.map do |old_name, new_name|
171
- "rename_column :#{new_table_name}, :#{old_name}, :#{new_name}"
172
- end
173
- undo_renames = to_rename.map do |old_name, new_name|
174
- "rename_column :#{new_table_name}, :#{new_name}, :#{old_name}"
175
- end
176
-
177
- to_add = to_add.sort_by{|c| model.field_specs[c].position }
178
- adds = to_add.map do |c|
179
- spec = model.field_specs[c]
180
- args = [":#{spec.sql_type}"] + format_options(spec.options, spec.sql_type)
181
- "add_column :#{new_table_name}, :#{c}, #{args * ', '}"
182
- end
183
- undo_adds = to_add.map do |c|
184
- "remove_column :#{new_table_name}, :#{c}"
185
- end
186
-
187
- removes = to_remove.map do |c|
188
- "remove_column :#{new_table_name}, :#{c}"
189
- end
190
- undo_removes = to_remove.map do |c|
191
- revert_column(new_table_name, c)
192
- end
193
-
194
- old_names = to_rename.invert
195
- changes = []
196
- undo_changes = []
197
- to_change.each do |c|
198
- col_name = old_names[c] || c
199
- col = db_columns[col_name]
200
- spec = model.field_specs[c]
201
- if spec.different_to?(col)
202
- change_spec = {}
203
- change_spec[:limit] = spec.limit unless spec.limit.nil?
204
- change_spec[:precision] = spec.precision unless spec.precision.nil?
205
- change_spec[:scale] = spec.scale unless spec.scale.nil?
206
- change_spec[:null] = false unless spec.null
207
- change_spec[:default] = spec.default unless spec.default.nil? && col.default.nil?
208
-
209
- changes << "change_column :#{new_table_name}, :#{c}, " +
210
- ([":#{spec.sql_type}"] + format_options(change_spec, spec.sql_type)).join(", ")
211
- back = change_column_back(new_table_name, c)
212
- undo_changes << back unless back.blank?
213
- else
214
- nil
215
- end
216
- end.compact
217
-
218
- [(renames + adds + removes + changes) * "\n",
219
- (undo_renames + undo_adds + undo_removes + undo_changes) * "\n"]
220
- end
221
-
222
-
223
- def format_options(options, type)
224
- options.map do |k, v|
225
- next if k == :limit && (type == :decimal || v == @types[type][:limit])
226
- next if k == :null && v == true
227
- "#{k.inspect} => #{v.inspect}"
228
- end.compact
229
- end
230
-
231
-
232
- def revert_table(table)
233
- res = StringIO.new
234
- ActiveRecord::SchemaDumper.send(:new, ActiveRecord::Base.connection).send(:table, table, res)
235
- res.string.strip.gsub("\n ", "\n")
236
- end
237
-
238
- def column_options_from_reverted_table(table, column)
239
- revert = revert_table(table)
240
- if (md = revert.match(/\s*t\.column\s+"#{column}",\s+(:[a-zA-Z0-9_]+)(?:,\s+(.*?)$)?/m))
241
- # Ugly migration
242
- _, type, options = *md
243
- elsif (md = revert.match(/\s*t\.([a-z_]+)\s+"#{column}"(?:,\s+(.*?)$)?/m))
244
- # Sexy migration
245
- _, type, options = *md
246
- type = ":#{type}"
247
- end
248
- [type, options]
249
- end
250
-
251
-
252
- def change_column_back(table, column)
253
- type, options = column_options_from_reverted_table(table, column)
254
- "change_column :#{table}, :#{column}, #{type}#{', ' + options.strip if options}"
255
- end
256
-
257
- def revert_column(table, column)
258
- type, options = column_options_from_reverted_table(table, column)
259
- "add_column :#{table}, :#{column}, #{type}#{', ' + options.strip if options}"
260
- end
261
-
262
-
263
- def input(prompt, options=nil)
264
- print(prompt + " ")
265
- if options
266
- while !(response = STDIN.readline.strip.downcase).in?(options);
267
- print(prompt + " ")
268
- end
269
- response
270
- else
271
- STDIN.readline
272
- end
273
- end
274
-
275
- end
276
-