hobo 0.7.2 → 0.7.3
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/hobo +24 -7
- data/hobo_files/plugin/CHANGES.txt +501 -0
- data/hobo_files/plugin/generators/hobo/hobo_generator.rb +8 -6
- data/hobo_files/plugin/generators/hobo/templates/application.dryml +3 -0
- data/hobo_files/plugin/generators/hobo/templates/dryml-support.js +132 -0
- data/hobo_files/plugin/generators/hobo_front_controller/hobo_front_controller_generator.rb +4 -5
- data/hobo_files/plugin/generators/hobo_model_resource/hobo_model_resource_generator.rb +75 -0
- data/hobo_files/plugin/generators/hobo_model_resource/templates/controller.rb +7 -0
- data/hobo_files/plugin/generators/hobo_model_resource/templates/functional_test.rb +8 -0
- data/hobo_files/plugin/generators/hobo_model_resource/templates/helper.rb +2 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/hobo-rapid.js +30 -11
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/application.css +149 -92
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/rapid-ui.css +0 -48
- data/hobo_files/plugin/init.rb +45 -13
- data/hobo_files/plugin/lib/action_view_extensions/base.rb +4 -3
- data/hobo_files/plugin/lib/active_record/association_proxy.rb +18 -0
- data/hobo_files/plugin/lib/active_record/association_reflection.rb +5 -0
- data/hobo_files/plugin/lib/active_record/has_many_association.rb +7 -11
- data/hobo_files/plugin/lib/active_record/has_many_through_association.rb +8 -0
- data/hobo_files/plugin/lib/extensions/test_case.rb +1 -1
- data/hobo_files/plugin/lib/hobo.rb +38 -60
- data/hobo_files/plugin/lib/hobo/authentication_support.rb +1 -1
- data/hobo_files/plugin/lib/hobo/bundle.rb +131 -34
- data/hobo_files/plugin/lib/hobo/composite_model.rb +1 -1
- data/hobo_files/plugin/lib/hobo/controller.rb +7 -8
- data/hobo_files/plugin/lib/hobo/dev_controller.rb +21 -0
- data/hobo_files/plugin/lib/hobo/dryml/dryml_builder.rb +14 -8
- data/hobo_files/plugin/lib/hobo/dryml/dryml_support_controller.rb +13 -0
- data/hobo_files/plugin/lib/hobo/dryml/taglib.rb +6 -7
- data/hobo_files/plugin/lib/hobo/dryml/template.rb +207 -73
- data/hobo_files/plugin/lib/hobo/dryml/template_environment.rb +67 -55
- data/hobo_files/plugin/lib/hobo/dryml/template_handler.rb +53 -3
- data/hobo_files/plugin/lib/hobo/hobo_helper.rb +75 -107
- data/hobo_files/plugin/lib/hobo/model.rb +236 -429
- data/hobo_files/plugin/lib/hobo/model_controller.rb +277 -437
- data/hobo_files/plugin/lib/hobo/model_router.rb +62 -29
- data/hobo_files/plugin/lib/hobo/rapid_helper.rb +48 -9
- data/hobo_files/plugin/lib/hobo/scopes.rb +98 -0
- data/hobo_files/plugin/lib/hobo/scopes/association_proxy_extensions.rb +31 -0
- data/hobo_files/plugin/lib/hobo/scopes/automatic_scopes.rb +282 -0
- data/hobo_files/plugin/lib/hobo/scopes/defined_scope_proxy_extender.rb +88 -0
- data/hobo_files/plugin/lib/hobo/scopes/scope_reflection.rb +18 -0
- data/hobo_files/plugin/lib/hobo/scopes/scoped_proxy.rb +59 -0
- data/hobo_files/plugin/lib/hobo/undefined.rb +2 -0
- data/hobo_files/plugin/lib/hobo/user.rb +31 -14
- data/hobo_files/plugin/lib/hobo/user_controller.rb +41 -27
- data/hobo_files/plugin/taglibs/core.dryml +9 -11
- data/hobo_files/plugin/taglibs/rapid.dryml +51 -108
- data/hobo_files/plugin/taglibs/rapid_editing.dryml +25 -25
- data/hobo_files/plugin/taglibs/rapid_forms.dryml +111 -79
- data/hobo_files/plugin/taglibs/rapid_generics.dryml +74 -0
- data/hobo_files/plugin/taglibs/rapid_navigation.dryml +23 -21
- data/hobo_files/plugin/taglibs/rapid_pages.dryml +83 -169
- data/hobo_files/plugin/taglibs/rapid_plus.dryml +16 -2
- data/hobo_files/plugin/taglibs/rapid_support.dryml +3 -3
- data/hobo_files/plugin/taglibs/rapid_user_pages.dryml +104 -0
- metadata +60 -55
- data/hobo_files/plugin/generators/hobo_migration/hobo_migration_generator.rb +0 -276
- data/hobo_files/plugin/generators/hobo_migration/templates/migration.rb +0 -9
- data/hobo_files/plugin/lib/active_record/table_definition.rb +0 -34
- data/hobo_files/plugin/lib/extensions.rb +0 -375
- data/hobo_files/plugin/lib/hobo/email_address.rb +0 -12
- data/hobo_files/plugin/lib/hobo/enum_string.rb +0 -50
- data/hobo_files/plugin/lib/hobo/field_declaration_dsl.rb +0 -43
- data/hobo_files/plugin/lib/hobo/field_spec.rb +0 -68
- data/hobo_files/plugin/lib/hobo/html_string.rb +0 -7
- data/hobo_files/plugin/lib/hobo/lazy_hash.rb +0 -40
- data/hobo_files/plugin/lib/hobo/markdown_string.rb +0 -11
- data/hobo_files/plugin/lib/hobo/migrations.rb +0 -12
- data/hobo_files/plugin/lib/hobo/model_queries.rb +0 -117
- data/hobo_files/plugin/lib/hobo/password_string.rb +0 -7
- data/hobo_files/plugin/lib/hobo/percentage.rb +0 -14
- data/hobo_files/plugin/lib/hobo/predicate_dispatch.rb +0 -78
- data/hobo_files/plugin/lib/hobo/proc_binding.rb +0 -32
- data/hobo_files/plugin/lib/hobo/text.rb +0 -3
- data/hobo_files/plugin/lib/hobo/textile_string.rb +0 -25
- 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,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,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,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
|