hobo 0.6.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/bin/hobo +3 -2
  2. data/hobo_files/plugin/CHANGES.txt +299 -2
  3. data/hobo_files/plugin/Rakefile +12 -10
  4. data/hobo_files/plugin/generators/hobo/templates/guest.rb +1 -13
  5. data/hobo_files/plugin/generators/hobo_migration/hobo_migration_generator.rb +11 -7
  6. data/hobo_files/plugin/generators/hobo_rapid/hobo_rapid_generator.rb +1 -0
  7. data/hobo_files/plugin/generators/hobo_rapid/templates/hobo_rapid.js +1 -1
  8. data/hobo_files/plugin/generators/hobo_rapid/templates/lowpro.js +405 -0
  9. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/views/application.dryml +1 -1
  10. data/hobo_files/plugin/generators/hobo_user_model/templates/model.rb +1 -9
  11. data/hobo_files/plugin/init.rb +5 -0
  12. data/hobo_files/plugin/lib/active_record/has_many_association.rb +1 -1
  13. data/hobo_files/plugin/lib/extensions.rb +26 -5
  14. data/hobo_files/plugin/lib/extensions/test_case.rb +1 -1
  15. data/hobo_files/plugin/lib/hobo.rb +37 -11
  16. data/hobo_files/plugin/lib/hobo/authenticated_user.rb +7 -2
  17. data/hobo_files/plugin/lib/hobo/authentication_support.rb +7 -6
  18. data/hobo_files/plugin/lib/hobo/composite_model.rb +5 -0
  19. data/hobo_files/plugin/lib/hobo/controller.rb +4 -4
  20. data/hobo_files/plugin/lib/hobo/dryml.rb +5 -5
  21. data/hobo_files/plugin/lib/hobo/dryml/part_context.rb +3 -6
  22. data/hobo_files/plugin/lib/hobo/dryml/template.rb +16 -15
  23. data/hobo_files/plugin/lib/hobo/dryml/template_environment.rb +24 -20
  24. data/hobo_files/plugin/lib/hobo/email_address.rb +4 -0
  25. data/hobo_files/plugin/lib/hobo/field_spec.rb +2 -1
  26. data/hobo_files/plugin/lib/hobo/guest.rb +21 -0
  27. data/hobo_files/plugin/lib/hobo/hobo_helper.rb +42 -2
  28. data/hobo_files/plugin/lib/hobo/http_parameters.rb +225 -0
  29. data/hobo_files/plugin/lib/hobo/model.rb +55 -37
  30. data/hobo_files/plugin/lib/hobo/model_controller.rb +151 -151
  31. data/hobo_files/plugin/lib/hobo/model_queries.rb +30 -5
  32. data/hobo_files/plugin/lib/hobo/user_controller.rb +27 -16
  33. data/hobo_files/plugin/lib/hobo/where_fragment.rb +6 -1
  34. data/hobo_files/plugin/tags/rapid.dryml +88 -58
  35. data/hobo_files/plugin/tags/rapid_document_tags.dryml +5 -5
  36. data/hobo_files/plugin/tags/rapid_editing.dryml +3 -3
  37. data/hobo_files/plugin/tags/rapid_forms.dryml +35 -26
  38. data/hobo_files/plugin/tags/rapid_navigation.dryml +13 -12
  39. data/hobo_files/plugin/tags/rapid_pages.dryml +35 -31
  40. data/hobo_files/plugin/tags/rapid_plus.dryml +41 -0
  41. data/hobo_files/plugin/tags/rapid_support.dryml +18 -9
  42. data/hobo_files/plugin/tasks/dump_fixtures.rake +61 -0
  43. metadata +7 -11
  44. data/hobo_files/plugin/spec/fixtures/users.yml +0 -9
  45. data/hobo_files/plugin/spec/spec.opts +0 -6
  46. data/hobo_files/plugin/spec/spec_helper.rb +0 -28
  47. data/hobo_files/plugin/spec/unit/hobo/dryml/template_spec.rb +0 -650
data/bin/hobo CHANGED
@@ -7,7 +7,7 @@ SRC_FILES = File.join(File.dirname(__FILE__), "../hobo_files")
7
7
 
8
8
  USAGE = "USAGE: hobo <app-path> [ --user-model <model-name-or-false> ] [ --svn ]"
9
9
 
10
- HOBO_REPO = "svn://hobocentral.net/hobo/trunk"
10
+ HOBO_REPO = "svn://hobocentral.net/hobo/trunk/hobo"
11
11
 
12
12
 
13
13
  ### Nasty stuff needed for Windows :-( ###
@@ -50,7 +50,8 @@ until ARGV.empty?
50
50
  end
51
51
  end
52
52
 
53
- command("mkdir #{app_path}")
53
+ FileUtils.mkdir_p(app_path) unless File.exists?(app_path)
54
+ (puts "App directory is not a directory!"; exit 1) unless File.directory?(app_path)
54
55
 
55
56
  Dir.chdir(app_path) do
56
57
  gen = "ruby #{File.join('script', 'generate')}"
@@ -1,3 +1,300 @@
1
+ === Release 0.6.2 ===
2
+
3
+ Specs
4
+
5
+ Moved out of the plugin source into a separate directory in the
6
+ hierarchy. If you check out hobo/trunk you'll get two directories:
7
+ hobo and hobo_spec. You can run "rake" from the hobo directory and
8
+ it should work as long as hobo_spec is along side. Note the
9
+ hobo_spec tree contains an svn external to edge rails.
10
+
11
+
12
+ New rake task dump_fixtures (which really should be nicely
13
+ namespaced). This will dump the current database into test
14
+ fixtures. The nice part is that it won't overwrite symbolic names
15
+ you've given to rows in your fixtures, so you can round-trip with it:
16
+ rake db:fixtures:load, run up the app and create some new data, rake
17
+ dump_fixtures.
18
+
19
+
20
+ Migration generator
21
+
22
+ Fixed indentation bug in generated code.
23
+
24
+ Now prompts for the name of the generated migration after the
25
+ generated code is displayed.
26
+
27
+ Better error message for invlaid field types declared in models.
28
+
29
+
30
+ Tabla theme
31
+
32
+ Fixed reference to non-existent human_type helper.
33
+
34
+
35
+ Hobo users
36
+
37
+ Various fixes to the new (in 0.6.1) multiple user model support.
38
+
39
+ If the model name is "User", the routes generated are simply:
40
+
41
+ /login
42
+ /logout
43
+ /signup
44
+
45
+ (as opposed to /user_login etc.)
46
+
47
+ The filter "login_required" can now be passed a user model (class),
48
+ e.g.
49
+
50
+ before_filter {|controller| controller.login_required(Administrator) }
51
+
52
+ The named routes "login", "logout" and "signup" are no longer
53
+ defined. Instead there are helpers login_url, signup_url and
54
+ logout_url, all of which are passed a user model (class) as
55
+ parameter.
56
+
57
+ New declaration 'hobo_user_model' can be used in place of hobo_model
58
+ and removes the need to include Hobo::AuthenticatedUser. Can be
59
+ passed the name of the login field, which removes the need to call
60
+ set_login_attr. Can also be passed a block in which to do
61
+ validations of the login attr (just as you can with set_login_attr).
62
+
63
+ User models now have a class method login_attr that returns the name
64
+ of the login attribute, e.g. :username
65
+
66
+ Guest model should now extend Hobo::Guest, which provides #guest
67
+ (true!) and #super_user (false)
68
+
69
+ User models now inherit #guest? (returns false). No need to define
70
+ it yourself.
71
+
72
+
73
+ Hobo models
74
+
75
+ Optimisation. Where possible we've replaced calls to #respond_to?
76
+ (which is slow on AR records) with the new class method
77
+ #has_hobo_method? which is an alias for
78
+ #respond_to_without_attributes?
79
+
80
+ "fields do" now supports shorthands for common validations
81
+ validates_uniqueness_of and validates_presence_of, e.g.:
82
+
83
+ fields do
84
+ name :string, :required, :unique
85
+ end
86
+
87
+ If you need to change the validation method, just go back to the
88
+ old way.
89
+
90
+ The creator attribute mechanism is updated to cope with multiple
91
+ user models. Hobo will not try to set the creator attribute if the
92
+ expected type is not the same as the type of the logged in user.
93
+
94
+ Various enhancements to composable query blocks
95
+
96
+ MyModel.has_creator? replaced with MyModel.creator_type which
97
+ returns the expected user class or nil if there is no creator
98
+ attribute.
99
+
100
+ Fix: def_scope was broken with has_many :through associations.
101
+
102
+
103
+ Integration test helpers
104
+
105
+ #logs_in_as updated to cope with multiple user types.
106
+
107
+
108
+ Core extensions
109
+
110
+ New method Object._? can be used to avoid an extra test for nil, e.g.
111
+
112
+ string_or_nil._?.length
113
+
114
+ is equivalent to
115
+
116
+ string_or_nil && string_or_nil.length
117
+
118
+ Hobo extensions to HashWithIndifferentAccess fixed to always return
119
+ indifferent hashes.
120
+
121
+
122
+ Hobo controller
123
+
124
+ Fix to #render_tags (problem with part contexts javascript)
125
+
126
+ Fix to include_taglib declaration (was not working in production
127
+ mode).
128
+
129
+
130
+ Hobo model controller
131
+
132
+ Largely re-written handling of http PUT and POST (update &
133
+ create). The new mechanism is more secure, more featureful and is
134
+ transactional. If your put/post affects multiple database rows, they
135
+ will either all happen or none will. See the model_controller_spec
136
+ for some good examples of what is allowed / possible.
137
+
138
+ def_data_filter is gone. Instead you can declare data filters from
139
+ within the action methods:
140
+
141
+ def index
142
+ data_filter :search do |query|
143
+ name_contains(query) | address_contains(query)
144
+ end
145
+ hobo_index
146
+ end
147
+
148
+ Declare data filters for autocompleters in the same way by giving
149
+ a block to autocomplete_for
150
+
151
+ #index now supports a "sort" parameter. The value should be
152
+ <field-name> or <model>.<field-name>. Precede with a '-' to sort in
153
+ descending order. e.g.
154
+
155
+ http://host/users?sort=-username
156
+
157
+ Provide the :order parameter to hobo_index to disable.
158
+
159
+ The mechanism to call a tag <ShowPage> if there is no show.dryml is
160
+ extended to work with any action name. So e.g. you can define
161
+ <FooPage> as an application wide page for any action "foo".
162
+
163
+
164
+ Hobo user controller
165
+
166
+ Options can now be given as procs, in which case they are called
167
+ only when needed and hence have access to things like current_user
168
+ (e.g. the redirect destination for a logged in user can take into
169
+ account who the user is)
170
+
171
+ #hobo_login can be given a block -- a place to check if the users
172
+ account is available. Return false to prevent the user from loggin
173
+ in.
174
+
175
+
176
+ Hobo module
177
+
178
+ #can_view? can now be given dotted field paths. E.g:
179
+
180
+ Hobo.can_view(current_user, post, "author.name")
181
+
182
+
183
+ Hobo Rapid
184
+
185
+ Adding low_pro.js (from the UJS project). First step towards
186
+ complete adoption of unobstrusive JavaScript.
187
+
188
+ Fix to client side of new ajax mechanism. Had problems with not URL
189
+ encoding part state.
190
+
191
+ New taglib rapid_plus, home of tags with an extra level of
192
+ functionality. First and only tag: <TablePlus> a table with
193
+ automatic support for sorting by clicking on column headings, and
194
+ filtering rows via a search field.
195
+
196
+ <Table> now supports tempalte parameters for each cell when given a
197
+ 'fields' attribute, e.g. <name_view> <address_view> (<name_cell>
198
+ might seem like a better name, but we wanted to be compatible with
199
+ <FieldList> so it's easy to flip back and forth).
200
+
201
+ <name> tag now respects view permission.
202
+
203
+ <a action="new"> now only renders the link if the current user has
204
+ the required create permission.
205
+
206
+ <view> now supports attribute 'truncate'
207
+
208
+ <view for_type="Date"> now supports a 'format' attribute - a
209
+ strftime style format string.
210
+
211
+ New tag <restricted_page>. Sometimes permissions are a view layer
212
+ concern - you actually want to say "these colors, this logo,
213
+ etc. are only to be seen by the administrator".
214
+
215
+ <restricted_page login_required="Administrator"/>
216
+
217
+ New tag <you_have>. An easy way to say either "You have 3 posts in
218
+ this thread" or "Fred Blogs has 3 posts in this thread", depending
219
+ on whether Fred Blogs is the current user.
220
+
221
+ Fixes to the tags in rapid_documents to avoid evaling tagbody twice.
222
+
223
+ <hidden_fields> fixed (was outputing hidden fields even when the
224
+ field existed in the form). Also now support "for_query_string"
225
+ attribute, to output hidden fields for the name/value pairs in the
226
+ current query string.
227
+
228
+ <form> now sets a scoped variable "in_form" so tags can behave
229
+ differently when they are inside a form (FieldList does this).
230
+
231
+ <input> for datetime and date now supports the same attributes as
232
+ the equivalent rails helpers. e.g. you can change the order of the
233
+ fields.
234
+
235
+ <belongs_to_menu_input> can now be passed an array of records in the
236
+ "options" attribute (instead of retrieving the entire target table
237
+ from the DB).
238
+
239
+ Fixes to page navigation
240
+
241
+ <account_nav> upgraded to cope with multiple user models.
242
+
243
+ Rapid pages:
244
+
245
+ Various new template params made available, including many on
246
+ login and signup pages.
247
+
248
+ <Page> updated for multiple user models
249
+
250
+ <IndexPage> fix to ajax updating of record count
251
+
252
+ New css classes added to <NewPage> and <EditPage>
253
+
254
+ <error_messages> added to <EditPage>
255
+
256
+ Fix to new link in <ShowCollectionPage>
257
+
258
+ <image> tag removed from default ajax progress.
259
+
260
+
261
+
262
+
263
+
264
+ Dryml
265
+
266
+ Important change ommitted from 0.6 changelog - attributes passed to
267
+ the tag that are not in the tags declared attributes are available
268
+ in a local variable "attributes" (used to be called "options").
269
+
270
+ <set> can now assign to dotted named (object attributes) as well as
271
+ locals, and can have controll attributes on it (e.g. if)
272
+
273
+ Fix to replacing template parameters that are themselves templates.
274
+
275
+ When a boolean is in context, this_type is now always TrueClass
276
+ (never FalseClass even if the value is false). TrueClass is the Hobo
277
+ boolean type.
278
+
279
+ #render_tag on a page renderer object (Dryml internals) now returns
280
+ false. This alows Hobo's controller to say "call this tag if it
281
+ exists, otherwise..."
282
+
283
+
284
+ Rich types
285
+
286
+ Registered rich types can now provide there own validations that get
287
+ added to the model automatically. E.g. Hobo::EmailAddress
288
+ automatically validates the content as a valid email address.
289
+
290
+
291
+ Hobo helpers
292
+
293
+ New helper query_params returns a hash of parameters extracted from
294
+ the query string only (#params returns route-based parameters
295
+ too). Only works with simple name=value parameters.
296
+
297
+
1
298
  === Release 0.6.1 ===
2
299
 
3
300
  Multiple user models
@@ -17,7 +314,7 @@ Multiple user models
17
314
  /admin_logout
18
315
  /admin_signup
19
316
 
20
- Note this controller will now filter loggin of passwords.
317
+ Note this controller will now filter logging of passwords.
21
318
 
22
319
  The model needs to include Hobo::AuthenticatedUser and declare a
23
320
  login attribute with, e.g.
@@ -306,7 +603,7 @@ Hobo Rapid
306
603
  not have edit permission. <editor> is a polymorphic tag, so you
307
604
  can <def tag="editor" for="MyClass">
308
605
 
309
- <form_field> is now <input>. If you give a type attributes, you
606
+ <form_field> is now <input>. If you give a type attribute, you
310
607
  get a regular html input tag, if you don't you get a smart Hobo
311
608
  form field appropriate for the type of the context. <input> is a
312
609
  polymorphic tag, so you can <def tag="input" for="MyClass">
@@ -2,7 +2,7 @@ require 'rake'
2
2
  require 'rake/rdoctask'
3
3
  require 'rake/testtask'
4
4
 
5
- desc 'Default: run unit tests.'
5
+ desc 'Default: run specs.'
6
6
  task :default => :spec
7
7
 
8
8
  desc 'Generate documentation for the Hobo plugin.'
@@ -34,17 +34,19 @@ end
34
34
 
35
35
  task :stats => "spec:statsetup"
36
36
 
37
+ SPEC_HOME = "#{PLUGIN_DIR}/../hobo_spec"
38
+
37
39
  desc "Run all specs in spec directory (excluding plugin specs)"
38
40
  Spec::Rake::SpecTask.new(:spec => spec_prereq) do |t|
39
- t.spec_opts = ['--options', "\"#{PLUGIN_DIR}/spec/spec.opts\""]
40
- t.spec_files = FileList['spec/unit/**/*_spec.rb']
41
+ t.spec_opts = ['--options', "\"#{SPEC_HOME}/spec.opts\""]
42
+ t.spec_files = FileList["#{SPEC_HOME}/unit/**/*_spec.rb"]
41
43
  end
42
44
 
43
45
  namespace :spec do
44
46
  desc "Run all specs in spec directory with RCov (excluding plugin specs)"
45
47
  Spec::Rake::SpecTask.new(:rcov) do |t|
46
- t.spec_opts = ['--options', "\"#{PLUGIN_DIR}/spec/spec.opts\""]
47
- t.spec_files = FileList['spec/unit/**/*_spec.rb']
48
+ t.spec_opts = ['--options', "\"#{SPEC_HOME}/spec.opts\""]
49
+ t.spec_files = FileList["#{SPEC_HOME}/unit/**/*_spec.rb"]
48
50
  t.rcov = true
49
51
  t.rcov_opts = ['--exclude', 'spec', '--rails']
50
52
  end
@@ -52,14 +54,14 @@ namespace :spec do
52
54
  desc "Print Specdoc for all specs (excluding plugin specs)"
53
55
  Spec::Rake::SpecTask.new(:doc) do |t|
54
56
  t.spec_opts = ["--format", "specdoc", "--dry-run"]
55
- t.spec_files = FileList['spec/unit/**/*_spec.rb']
57
+ t.spec_files = FileList["#{SPEC_HOME}/unit/**/*_spec.rb"]
56
58
  end
57
59
 
58
60
  [:models, :controllers, :views, :helpers].each do |sub|
59
61
  desc "Run the specs under spec/#{sub}"
60
62
  Spec::Rake::SpecTask.new(sub => spec_prereq) do |t|
61
- t.spec_opts = ['--options', "\"#{PLUGIN_DIR}/spec/spec.opts\""]
62
- t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
63
+ t.spec_opts = ['--options', "\"#{SPEC_HOME}/spec.opts\""]
64
+ t.spec_files = FileList["#{SPEC_HOME}/#{sub}/**/*_spec.rb"]
63
65
  end
64
66
  end
65
67
 
@@ -83,8 +85,8 @@ namespace :spec do
83
85
  task :load => :environment do
84
86
  require 'active_record/fixtures'
85
87
  ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
86
- (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(PLUGIN_DIR, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
87
- Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*'))
88
+ (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(SPEC_HOME, 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
89
+ Fixtures.create_fixtures("#{SPEC_HOME}/fixtures", File.basename(fixture_file, '.*'))
88
90
  end
89
91
  end
90
92
  end
@@ -1,16 +1,4 @@
1
- class Guest
2
-
3
- def to_s
4
- "Guest"
5
- end
6
-
7
- def guest?
8
- true
9
- end
10
-
11
- def super_user?
12
- false
13
- end
1
+ class Guest < Hobo::Guest
14
2
 
15
3
  def can_update?(obj, field)
16
4
  false
@@ -68,26 +68,30 @@ class HoboMigrationGenerator < Rails::Generator::Base
68
68
 
69
69
  return record {|m| } if up.blank?
70
70
 
71
- up.gsub!("\n", "\n ")
72
- down.gsub!("\n", "\n ")
73
-
74
71
  action = input("What now: [g]enerate migrations, generate and [m]igrate now or [c]ancel?", %w(g m c))
75
72
 
76
73
  if action == 'c'
77
74
  # record nothing to keep the generator happy
78
75
  record {|m| }
79
76
  else
80
- at_exit { system "rake db:migrate" } if action == 'm'
77
+ puts "\n(you can type spaces instead of '_' -- every little helps)"
78
+ migration_name = input("Migration filename [#@migration_name]:").strip.gsub(' ', '_')
79
+ migration_name = @migration_name if migration_name.blank?
80
+
81
+ at_exit { system "rake db:migrate" } if action == 'm'
81
82
 
82
83
  up.gsub!("\n", "\n ")
83
84
  down.gsub!("\n", "\n ")
84
85
 
85
86
  record do |m|
86
87
  m.migration_template 'migration.rb', 'db/migrate',
87
- :assigns => { :up => up, :down => down, :migration_name => @migration_name.camelize },
88
- :migration_file_name => @migration_name
88
+ :assigns => { :up => up, :down => down, :migration_name => migration_name.camelize },
89
+ :migration_file_name => migration_name
89
90
  end
90
91
  end
92
+ rescue Hobo::FieldSpec::UnknownSqlTypeError => e
93
+ puts "Invalid field type '#{e.message[2]}' for #{e.message[0]}.#{e.message[1]}"
94
+ record {|m| }
91
95
  end
92
96
 
93
97
  def rename_or_drop!(to_create, to_drop, kind_str, name_prefix="")
@@ -206,7 +210,7 @@ class HoboMigrationGenerator < Rails::Generator::Base
206
210
  next if k == :limit && (type == :decimal || v == @types[type][:limit])
207
211
  next if k == :null && v == true
208
212
  "#{k.inspect} => #{v.inspect}"
209
- end.compact
213
+ end.compact
210
214
  end
211
215
 
212
216