hobo 0.7.2 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,43 +0,0 @@
1
- module Hobo
2
-
3
- class FieldDeclarationsDsl
4
-
5
- def initialize(model)
6
- @model = model
7
- end
8
-
9
- attr_reader :model
10
-
11
- def timestamps
12
- field(:created_at, :datetime)
13
- field(:updated_at, :datetime)
14
- end
15
-
16
- def field(name, *args)
17
- type = args.shift
18
- options = args.extract_options!
19
-
20
- @model.name_attribute = name.to_sym if options.delete(:name)
21
- @model.primary_content_attribute = name.to_sym if options.delete(:description)
22
- @model.creator_attribute = name.to_sym if options.delete(:creator)
23
-
24
- @model.send(:login_attribute=, name.to_sym, options.delete(:validate)) if @model < User && options.delete(:login)
25
-
26
- @model.send(:set_field_type, name => type) unless
27
- type.in?(@model.connection.native_database_types.keys - [:text])
28
- @model.field_specs[name] = FieldSpec.new(@model, name, type, options)
29
-
30
- @model.send(:validates_presence_of, name) if :required.in?(args)
31
- @model.send(:validates_uniqueness_of, name) if :unique.in?(args)
32
- end
33
-
34
- def method_missing(name, *args)
35
- field(name, *args)
36
- end
37
-
38
- undef_method :type
39
-
40
-
41
- end
42
-
43
- end
@@ -1,68 +0,0 @@
1
- module Hobo
2
-
3
- class FieldSpec
4
-
5
- class UnknownSqlTypeError < RuntimeError; end
6
-
7
- def initialize(model, name, type, options={})
8
- raise ArgumentError, "you cannot provide a field spec for the primary key" if name == model.primary_key
9
- self.model = model
10
- self.name = name.to_sym
11
- self.type = type.is_a?(String) ? type.to_sym : type
12
- self.options = options
13
- self.position = model.field_specs.length
14
- end
15
-
16
- attr_accessor :model, :name, :type, :position, :options
17
-
18
- def sql_type
19
- options[:sql_type] or begin
20
- native_types = model.connection.native_database_types.keys - [:primary_key]
21
- if type.in?(native_types)
22
- type
23
- else
24
- field_type = type.is_a?(Class) ? type : Hobo.field_types[type]
25
- field_type && field_type::COLUMN_TYPE or raise UnknownSqlTypeError, [model, name, type]
26
- end
27
- end
28
- end
29
-
30
- def limit
31
- options[:limit] || types[sql_type][:limit]
32
- end
33
-
34
- def precision
35
- options[:precision]
36
- end
37
-
38
- def scale
39
- options[:scale]
40
- end
41
-
42
- def null
43
- :null.in?(options) ? options[:null] : true
44
- end
45
-
46
- def default
47
- options[:default]
48
- end
49
-
50
- def different_to?(col_spec)
51
- sql_type != col_spec.type ||
52
- begin
53
- check_cols = [:null, :default]
54
- check_cols += [:precision, :scale] if sql_type == :decimal
55
- check_cols << :limit if sql_type.in?([:string, :text, :binary, :integer])
56
- check_cols.any? { |k| col_spec.send(k) != self.send(k) }
57
- end
58
- end
59
-
60
- private
61
-
62
- def types
63
- @types ||= model.connection.native_database_types
64
- end
65
-
66
- end
67
-
68
- end
@@ -1,7 +0,0 @@
1
- class Hobo::HtmlString < String
2
-
3
- COLUMN_TYPE = :text
4
-
5
- end
6
-
7
- Hobo.field_types[:html] = Hobo::HtmlString
@@ -1,40 +0,0 @@
1
- class Hobo::LazyHash < Hash
2
-
3
- def initialize(hash=nil)
4
- if hash.is_a?(Hash)
5
- update(hash)
6
- else
7
- super
8
- end
9
- end
10
-
11
-
12
- def [](key)
13
- val = super
14
- if val.is_a?(Proc)
15
- self[val] = val.call
16
- else
17
- val
18
- end
19
- end
20
-
21
-
22
- def delete(key)
23
- val = super
24
- val.is_a?(Proc) ? val.call : val
25
- end
26
-
27
-
28
- def inspect
29
- pairs = map do |k, v|
30
- "#{k.inspect} => #{v.is_a?(Proc) ? '??' : v.inspect}"
31
- end
32
- "{#{pairs * ', '}}"
33
- end
34
-
35
-
36
- def to_s
37
- inspect
38
- end
39
-
40
- end
@@ -1,11 +0,0 @@
1
- class Hobo::MarkdownString < String
2
-
3
- COLUMN_TYPE = :text
4
-
5
- def to_html
6
- blank? ? "" : BlueCloth.new(self).to_html
7
- end
8
-
9
- end
10
-
11
- Hobo.field_types[:markdown] = Hobo::MarkdownString
@@ -1,12 +0,0 @@
1
- module Hobo::Migrations
2
-
3
- class << self
4
- attr_accessor :ignore_tables
5
- attr_accessor :ignore_models
6
- attr_accessor :ignore
7
- end
8
- self.ignore_tables = []
9
- self.ignore_models = []
10
- self.ignore = []
11
-
12
- end
@@ -1,117 +0,0 @@
1
- module Hobo
2
-
3
- class ModelQueries
4
-
5
- def initialize(model)
6
- @model = model
7
- end
8
-
9
-
10
- attr_reader :model
11
-
12
- def not_(fragment)
13
- WhereFragment.new("not (#{fragment.to_sql})")
14
- end
15
-
16
-
17
- def is_in(association)
18
- association = Hobo.object_from_dom_id(association) if association.is_a? String
19
- refl = association.proxy_reflection
20
- raise HoboError.new("association #{refl.name} is not a collection of #{model.name.pluralize}") unless
21
- refl.klass == model and refl.macro == :has_many
22
-
23
- WhereFragment.new(_association_finder_sql(association))
24
- end
25
-
26
-
27
- def not_in(association)
28
- not_(is_in(association))
29
- end
30
-
31
-
32
- def sql(s)
33
- WhereFragment.new(s)
34
- end
35
-
36
- def block(b)
37
- b && instance_eval(&b)
38
- end
39
-
40
-
41
- def all?(*args)
42
- args.inject { |m, a| m & a }
43
- end
44
-
45
- def any?(*args)
46
- args.inject { |m, a| m | a }
47
- end
48
-
49
- def method_missing(name, *args)
50
- check_column = proc do |col|
51
- raise HoboError.new("no such column '#{col}' in query") unless
52
- model.columns.every(:name).include? col
53
- end
54
-
55
- m, field = *name.to_s.match(/^(.*)_is$/)
56
- if m
57
- if (refl = model.reflections[field.to_sym]) && refl.macro == :belongs_to
58
- field = refl.primary_key_name
59
- val = args[0] && args[0].id
60
- raise HoboError.new("don't use self in query blocks") if val == self
61
- else
62
- check_column[field]
63
- val = args[0]
64
- end
65
- return (if val.nil?
66
- WhereFragment.new("#{_query_table}.#{field} IS NULL")
67
- else
68
- WhereFragment.new("#{_query_table}.#{field} = ?", val)
69
- end)
70
- end
71
-
72
- m, field = *name.to_s.match(/^(.*)_contains$/)
73
- if m
74
- check_column[field]
75
- return WhereFragment.new("#{_query_table}.#{field} like ?", "%#{args[0]}%")
76
- end
77
-
78
- m, field = *name.to_s.match(/^(.*)_starts$/)
79
- if m
80
- check_column[field]
81
- return WhereFragment.new("#{_query_table}.#{field} like ?", "#{args[0]}%")
82
- end
83
-
84
- m, field = *name.to_s.match(/^(.*)_ends$/)
85
- if m
86
- check_column[field]
87
- return WhereFragment.new("#{_query_table}.#{field} like ?", "%#{args[0]}")
88
- end
89
-
90
- if (refl = model.reflections[name.to_sym]) && refl.macro == :belongs_to
91
- return ModelQueries.new(refl.klass)
92
- end
93
-
94
- return WhereFragment.new(@model.send(name, *args))
95
- end
96
-
97
- def _association_finder_sql(assoc)
98
- refl = assoc.proxy_reflection
99
- if refl.through_reflection
100
- conditions = assoc.send(:construct_conditions)
101
- from = assoc.send(:construct_from)
102
- joins = assoc.send(:construct_joins)
103
-
104
- table = "#{model.table_name}"
105
- "id in (select #{table}.id from #{table} #{joins} where #{conditions})"
106
- else
107
- Object.instance_method(:instance_variable_get).bind(assoc).call("@finder_sql")
108
- end
109
- end
110
-
111
- def _query_table
112
- model.table_name
113
- end
114
-
115
- end
116
-
117
- end
@@ -1,7 +0,0 @@
1
- class Hobo::PasswordString < String
2
-
3
- COLUMN_TYPE = :string
4
-
5
- end
6
-
7
- Hobo.field_types[:password] = Hobo::PasswordString
@@ -1,14 +0,0 @@
1
- module Hobo
2
-
3
- class Percentage < DelegateClass(Fixnum)
4
-
5
- COLUMN_TYPE = :integer
6
-
7
- def validate
8
- "must be from 0 to 100" unless self.in?(0..100)
9
- end
10
-
11
- end
12
-
13
- end
14
- Hobo.field_types[:percentage] = Hobo::Percentage
@@ -1,78 +0,0 @@
1
- module Hobo::PredicateDispatch
2
-
3
- def self.included(base)
4
- base.extend(ClassMethods)
5
- end
6
-
7
- module ClassMethods
8
-
9
- def default_method_for(method)
10
- "_default_#{method}"
11
- end
12
-
13
- def defp(name, predicate=nil, &block)
14
- ivar = "@@#{name}_predicates"
15
- default_method_name = default_method_for(name).to_sym
16
- methods = ivar.in?(class_variables) && class_variable_get(ivar)
17
-
18
- if !methods
19
- # It's the first defp for this name...
20
-
21
- methods = class_variable_set(ivar, [])
22
-
23
- if name.to_s.in?(instance_methods) and predicate
24
- # There's already a normal method with this name - it
25
- # becomes the default.
26
- alias_method default_method_name, name
27
- end
28
-
29
- end
30
-
31
- if predicate
32
- pname = "#{name}_p#{methods.length}"
33
- methods << [pname, predicate.arity == 1, block.arity == 2]
34
- define_method(pname, block)
35
- define_method(pname + "_predicate", &predicate)
36
- else
37
- # It's the default - if there's already one, overwrite it
38
- define_method(default_method_name, block)
39
- end
40
-
41
- module_eval <<-END, __FILE__, __LINE__+1
42
- def #{name}(options={}, &block)
43
- methods = #{ivar}
44
- for method_name, predicate_wants_options, wants_block in methods
45
- pred = method_name + "_predicate"
46
- if (predicate_wants_options ? send(pred, options) : send(pred))
47
- return (if wants_block
48
- send(method_name, options, block)
49
- else
50
- send(method_name, options)
51
- end)
52
- end
53
- end
54
- if respond_to?(:#{default_method_name})
55
- if method(:#{default_method_name}).arity == 2
56
- #{default_method_name}(options, block)
57
- else
58
- #{default_method_name}(options)
59
- end
60
- end
61
- end
62
- END
63
- end
64
-
65
- alias :p :proc
66
-
67
- def predicate_method?(method_name)
68
- "@@#{method_name}_predicates".in?(class_variables)
69
- end
70
-
71
- def predicate_has_default?(method_name)
72
- default_method_for(method_name).in?(instance_methods)
73
- end
74
-
75
- end
76
-
77
-
78
- end
@@ -1,32 +0,0 @@
1
- module Hobo
2
-
3
- class ProcBinding
4
-
5
- def self.eval(proc, self_, locals)
6
- ProcBinding.new(self_, locals).instance_eval(&proc)
7
- end
8
-
9
- def initialize(self_, locals)
10
- @self_ = self_
11
- @locals = locals
12
- locals.symbolize_keys!
13
- end
14
-
15
- def method_missing(name, *args, &block)
16
- if @locals.has_key?(name)
17
- @locals[name]
18
- else
19
- @self_.send(name, *args, &block)
20
- end
21
- end
22
-
23
- end
24
-
25
- (Object.instance_methods +
26
- Object.private_instance_methods +
27
- Object.protected_instance_methods).each do |m|
28
- ProcBinding.send(:undef_method, m) unless
29
- %w{initialize method_missing send instance_eval}.include?(m) || m.starts_with?('_')
30
- end
31
-
32
- end
@@ -1,3 +0,0 @@
1
- class Hobo::Text < String; end
2
-
3
- Hobo.field_types[:text] = Hobo::Text