lolita 3.0.7 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. data/GUIDELINE +4 -0
  2. data/README.rdoc +50 -0
  3. data/VERSION +1 -1
  4. data/app/controllers/lolita/rest_controller.rb +27 -11
  5. data/app/helpers/components/lolita/configuration/list_component.rb +11 -0
  6. data/app/helpers/lolita_helper.rb +1 -1
  7. data/app/views/components/lolita/configuration/field/_display.html.erb +9 -0
  8. data/app/views/components/lolita/configuration/field/_label.html.erb +1 -0
  9. data/app/views/components/lolita/{field → configuration/field}/_object.html.erb +0 -0
  10. data/app/views/components/lolita/configuration/field/array/_display.html.erb +5 -0
  11. data/app/views/components/lolita/configuration/field/array/habtm/_display.html.erb +26 -0
  12. data/app/views/components/lolita/configuration/field/array/select/_display.html.erb +5 -0
  13. data/app/views/components/lolita/configuration/field/big_decimal/_display.html.erb +1 -0
  14. data/app/views/components/lolita/{field/_boolean.html.erb → configuration/field/boolean/_display.html.erb} +0 -0
  15. data/app/views/components/lolita/configuration/field/date/_display.html.erb +1 -0
  16. data/app/views/components/lolita/{field/_string.html.erb → configuration/field/float/_display.html.erb} +0 -0
  17. data/app/views/components/lolita/configuration/field/integer/_display.html.erb +1 -0
  18. data/app/views/components/lolita/configuration/field/string/_display.html.erb +5 -0
  19. data/app/views/components/lolita/{field/_disabled.html.erb → configuration/field/string/disabled/_display.html.erb} +0 -0
  20. data/app/views/components/lolita/{field/_password.html.erb → configuration/field/string/password/_display.html.erb} +0 -0
  21. data/app/views/components/lolita/configuration/field/string/text/_display.html.erb +34 -0
  22. data/app/views/components/lolita/configuration/field/time/_display.html.erb +1 -0
  23. data/app/views/components/lolita/{field_set → configuration/field_set}/_display.html.erb +1 -1
  24. data/app/views/components/lolita/configuration/list/_body.html.erb +5 -0
  25. data/app/views/components/lolita/{list → configuration/list}/_body_cell.html.erb +0 -0
  26. data/app/views/components/lolita/{list → configuration/list}/_checkbox_cell.html.erb +0 -0
  27. data/app/views/components/lolita/{list → configuration/list}/_checkbox_header.html.erb +0 -0
  28. data/app/views/components/lolita/configuration/list/_display.html.erb +12 -0
  29. data/app/views/components/lolita/configuration/list/_filter.html.erb +8 -0
  30. data/app/views/components/lolita/configuration/list/_header.html.erb +9 -0
  31. data/app/views/components/lolita/{list → configuration/list}/_header_cell.html.erb +0 -0
  32. data/app/views/components/lolita/{list → configuration/list}/_new_resource.html.erb +0 -0
  33. data/app/views/components/lolita/configuration/list/_paginator.html.erb +3 -0
  34. data/app/views/components/lolita/configuration/list/_row.html.erb +7 -0
  35. data/app/views/components/lolita/{list → configuration/list}/_title.html.erb +0 -0
  36. data/app/views/components/lolita/{list → configuration/list}/_tool_cell.html.erb +0 -0
  37. data/app/views/components/lolita/{list → configuration/list}/_tool_header.html.erb +0 -0
  38. data/app/views/components/lolita/configuration/tab/_display.html.erb +17 -0
  39. data/app/views/components/lolita/configuration/tab/_fields.html.erb +7 -0
  40. data/app/views/components/lolita/configuration/tab/content/_display.html.erb +1 -0
  41. data/app/views/components/lolita/configuration/tab/default/_display.html.erb +9 -0
  42. data/app/views/components/lolita/{tabs → configuration/tabs}/_display.html.erb +4 -3
  43. data/app/views/{lolita/layouts → layouts/lolita}/application.html.erb +0 -0
  44. data/app/views/{lolita/layouts → layouts/lolita}/application.html.erb_spec.rb +0 -0
  45. data/author +1 -1
  46. data/lib/lolita.rb +31 -12
  47. data/lib/lolita/adapter/active_record.rb +16 -5
  48. data/lib/lolita/adapter/mongoid.rb +2 -2
  49. data/lib/lolita/base_configuration.rb +44 -2
  50. data/lib/lolita/builder.rb +31 -14
  51. data/lib/lolita/configuration/column.rb +92 -86
  52. data/lib/lolita/configuration/columns.rb +65 -65
  53. data/lib/lolita/configuration/factory.rb +8 -8
  54. data/lib/lolita/configuration/field.rb +156 -100
  55. data/lib/lolita/configuration/field/array.rb +74 -0
  56. data/lib/lolita/configuration/field/big_decimal.rb +12 -0
  57. data/lib/lolita/configuration/field/boolean.rb +7 -5
  58. data/lib/lolita/configuration/field/date.rb +13 -0
  59. data/lib/lolita/configuration/field/integer.rb +7 -5
  60. data/lib/lolita/configuration/field/string.rb +8 -6
  61. data/lib/lolita/configuration/field/time.rb +13 -0
  62. data/lib/lolita/configuration/fields.rb +36 -0
  63. data/lib/lolita/configuration/filter.rb +63 -0
  64. data/lib/lolita/configuration/list.rb +101 -91
  65. data/lib/lolita/configuration/page.rb +1 -0
  66. data/lib/lolita/configuration/tab.rb +137 -131
  67. data/lib/lolita/configuration/tab/content.rb +14 -12
  68. data/lib/lolita/configuration/tab/default.rb +15 -13
  69. data/lib/lolita/configuration/tabs.rb +2 -2
  70. data/lib/lolita/controllers/component_helpers.rb +26 -14
  71. data/lib/lolita/controllers/internal_helpers.rb +14 -0
  72. data/lib/lolita/controllers/url_helpers.rb +47 -10
  73. data/lib/lolita/dbi/base.rb +50 -50
  74. data/lib/lolita/errors.rb +2 -2
  75. data/lib/lolita/hooks.rb +298 -0
  76. data/lib/lolita/hooks/named_hook.rb +122 -0
  77. data/lib/lolita/lazy_loader.rb +46 -46
  78. data/lib/lolita/mapping.rb +3 -2
  79. data/lib/lolita/navigation.rb +48 -0
  80. data/lib/lolita/observed_array.rb +7 -0
  81. data/lib/lolita/rails/routes.rb +29 -3
  82. data/lolita.gemspec +65 -48
  83. data/public/javascripts/lolita/tab.js +5 -0
  84. data/public/javascripts/rails.js +137 -137
  85. data/public/stylesheets/lolita/style.css +3 -1
  86. data/spec/builder_spec.rb +42 -0
  87. data/spec/configuration/field_spec.rb +29 -18
  88. data/spec/configuration/filter_spec.rb +60 -0
  89. data/spec/configuration/tab_spec.rb +28 -20
  90. data/spec/configuration/tabs_spec.rb +8 -4
  91. data/spec/controllers/lolita_rest_spec.rb +15 -0
  92. data/spec/hooks_spec.rb +191 -0
  93. data/spec/lolita_spec.rb +6 -4
  94. data/spec/navigation/tree_spec.rb +59 -0
  95. data/spec/rails_app/app/mongoid/post.rb +2 -0
  96. data/spec/rails_app/app/views/components/lolita/{list → configuration/list}/_body_cell.html.erb +0 -0
  97. data/spec/rails_app/config/application.rb +1 -0
  98. data/spec/rails_app/lib/lolita/configuration/field/my_custom_collection.rb +14 -0
  99. data/spec/simple_spec_helper.rb +1 -0
  100. data/spec/spec_helper.rb +1 -2
  101. metadata +66 -49
  102. data/README.md +0 -5
  103. data/app/helpers/components/lolita/list_component.rb +0 -9
  104. data/app/views/components/lolita/field/_collection.html.erb +0 -5
  105. data/app/views/components/lolita/field/_date.html.erb +0 -1
  106. data/app/views/components/lolita/field/_datetime.html.erb +0 -1
  107. data/app/views/components/lolita/field/_display.html.erb +0 -6
  108. data/app/views/components/lolita/field/_integer.html.erb +0 -1
  109. data/app/views/components/lolita/field/_label.html.erb +0 -1
  110. data/app/views/components/lolita/field/_select.html.erb +0 -1
  111. data/app/views/components/lolita/field/_text.html.erb +0 -27
  112. data/app/views/components/lolita/list/_body.html.erb +0 -5
  113. data/app/views/components/lolita/list/_display.html.erb +0 -11
  114. data/app/views/components/lolita/list/_header.html.erb +0 -9
  115. data/app/views/components/lolita/list/_paginator.html.erb +0 -4
  116. data/app/views/components/lolita/list/_row.html.erb +0 -7
  117. data/app/views/components/lolita/tab/_content.html.erb +0 -1
  118. data/app/views/components/lolita/tab/_default.html.erb +0 -11
  119. data/app/views/components/lolita/tab/_display.html.erb +0 -7
  120. data/app/views/components/lolita/tab/_fields.html.erb +0 -7
  121. data/lib/lolita/configuration/field/collection.rb +0 -71
  122. data/lib/lolita/configuration/field/datetime.rb +0 -10
  123. data/lib/lolita/configuration/field/disabled.rb +0 -10
  124. data/lib/lolita/configuration/field/password.rb +0 -10
  125. data/lib/lolita/configuration/field/text.rb +0 -10
  126. data/lib/lolita/hooks/base.rb +0 -58
  127. data/lib/lolita/hooks/component.rb +0 -15
  128. data/lib/lolita/hooks/hooks.rb +0 -15
@@ -10,7 +10,7 @@ module Lolita
10
10
  def add(dbi,*args,&block)
11
11
  @create_temp_object=true
12
12
  begin
13
- temp_object=self.new(dbi,*args,&block)
13
+ temp_object=self.const_get(:Base).new(dbi,*args,&block)
14
14
  rescue Exception => e
15
15
  raise e
16
16
  ensure
@@ -24,21 +24,21 @@ module Lolita
24
24
 
25
25
  def factory(name)
26
26
  begin
27
- Lolita::Configuration.const_get(:"#{to_class(name)}#{factory_name}")
28
- rescue
29
- error_class=Lolita.const_get(:"#{factory_name}NotFoundError")
30
- raise error_class, "Can't find field Lolita::Configuration::#{to_class(name)}#{factory_name}. Add in /configuration/#{factory_name.downcase}/#{name.to_s.downcase}.rb"
27
+ self.const_get(:"#{to_class(name)}")
28
+ rescue NameError
29
+ error_class=Lolita::ConfigurationClassNotFound
30
+ raise error_class, "Can't find #{self}::#{to_class(name)}. Should be in /configuration/#{factory_name}/#{name}.rb"
31
31
  end
32
32
  end
33
33
 
34
34
  def to_class(name)
35
- name.to_s.downcase.gsub(/_\w/) do |m|
35
+ name.to_s.downcase.gsub(/_id$/, "").gsub(/(^\w|_\w)/) do |m|
36
36
  m.gsub("_","").upcase
37
- end.humanize
37
+ end
38
38
  end
39
39
 
40
40
  def factory_name
41
- @factory_name||=self.to_s.split("::").last
41
+ @factory_name||=self.to_s.split("::").last.downcase
42
42
  @factory_name
43
43
  end
44
44
  end
@@ -23,133 +23,189 @@ module Lolita
23
23
  # end
24
24
  # end
25
25
  # end
26
- class Field
27
- extend Lolita::Configuration::Factory
26
+ module Field
28
27
 
29
- @@default_type="string"
30
- lolita_accessor :name,:title,:type,:field_set,:nested_for,:options, :html_options,:record,:association
31
- attr_reader :dbi,:nested_in
32
-
33
- def initialize dbi, *args, &block
34
- @dbi=dbi
35
- begin
36
- self.set_attributes(*args)
37
- self.instance_eval(&block) if block_given?
38
- set_default_values
39
- validate
40
- rescue Exception=>e
41
- unless self.class.temp_object?
42
- raise e
28
+ class Base
29
+ include Lolita::Builder
30
+
31
+ @@default_type="string"
32
+ lolita_accessor :name,:title,:field_set,:nested_for,:options, :html_options,:record,:association
33
+ attr_reader :dbi,:nested_in
34
+
35
+ def initialize dbi, *args, &block
36
+ @dbi=dbi
37
+ before_init(*args)
38
+ begin
39
+ self.set_attributes(*args)
40
+ if block_given?
41
+ self.instance_eval(&block)
42
+ process_type unless @type
43
+ end
44
+ set_default_values
45
+ validate
46
+ rescue Exception=>e
47
+ unless Lolita::Configuration::Field.temp_object?
48
+ raise e
49
+ end
43
50
  end
44
51
  end
45
- end
46
-
47
- def value value=nil, &block
48
- self.send(:value=,value,&block) if value || block_given?
49
- unless @value
50
- self.record_value
51
- else
52
- if @value.is_a?(Proc)
53
- @value.call(self)
52
+
53
+ def value value=nil, &block
54
+ self.send(:value=,value,&block) if value || block_given?
55
+ unless @value
56
+ self.record_value
54
57
  else
55
- @value
58
+ if @value.is_a?(Proc)
59
+ @value.call(self)
60
+ else
61
+ @value
62
+ end
56
63
  end
57
64
  end
58
- end
59
65
 
60
- def value=(value=nil,&block)
61
- if block_given?
62
- @value=block
63
- else
64
- @value=value
66
+ def value=(value=nil,&block)
67
+ if block_given?
68
+ @value=block
69
+ else
70
+ @value=value
71
+ end
72
+ end
73
+
74
+ def type value=nil
75
+ @type=value.to_s.underscore if value
76
+ @type
65
77
  end
66
- end
67
78
 
68
- def name=(value)
69
- @name=value.to_sym
70
- end
79
+ def type=(value)
80
+ @type=value ? value.to_s.underscore : nil
81
+ end
71
82
 
72
- def type_name
73
- self.type.to_s.downcase
74
- end
83
+ def name=(value)
84
+ @name=value ? value.to_sym : nil
85
+ end
75
86
 
76
- def nested_in=(dbi)
77
- unless self.dbi.associations_class_names.include?(dbi.klass.to_s)
78
- raise Lolita::ReferenceError, "There is no association between #{self.dbi.klass} and #{dbi.klass}"
87
+ def type_name
88
+ self.type.to_s.downcase
79
89
  end
80
- raise ArgumentError, "Field can be nested only in Lolita::DBI::Base object." unless dbi.is_a?(Lolita::DBI::Base)
81
- @nested_in=dbi
82
- end
83
-
84
- def nested?
85
- !self.nested_in.nil?
86
- end
87
90
 
88
- def nested_in?(dbi_or_class)
89
- if dbi_or_class.is_a?(Lolita::DBI::Base)
90
- self.nested_in && self.nested_in.klass==dbi_or_class.klass
91
- else
92
- self.nested_in && self.nested_in.klass==dbi_or_class
91
+ def nested_in=(dbi)
92
+ unless self.dbi.associations_class_names.include?(dbi.klass.to_s)
93
+ raise Lolita::ReferenceError, "There is no association between #{self.dbi.klass} and #{dbi.klass}"
94
+ end
95
+ raise ArgumentError, "Field can be nested only in Lolita::DBI::Base object." unless dbi.is_a?(Lolita::DBI::Base)
96
+ @nested_in=dbi
97
+ end
98
+
99
+ def nested?
100
+ !self.nested_in.nil?
101
+ end
102
+
103
+ def nested_in?(dbi_or_class)
104
+ if dbi_or_class.is_a?(Lolita::DBI::Base)
105
+ self.nested_in && self.nested_in.klass==dbi_or_class.klass
106
+ else
107
+ self.nested_in && self.nested_in.klass==dbi_or_class
108
+ end
93
109
  end
94
- end
95
110
 
96
- def set_attributes(*args)
97
- if args
98
- attributes=args.extract_options!
99
- self.name=args.first if args.first
100
- self.type=args[1] if args[1]
101
- attributes.each{|attr,value|
102
- self.send(:"#{attr}=",value)
111
+
112
+ def set_attributes(*args)
113
+ @given_attributes.each{|attr,value|
114
+ if (attr.to_sym==:type && !@type) || attr.to_sym!=:type
115
+ self.send(:"#{attr}=",value)
116
+ end
103
117
  }
104
118
  end
105
- end
106
119
 
107
- # TODO is this useable
108
- def record_value #TODO test
109
- if self.record
110
- self.record.send(self.name.to_sym)
111
- else
112
- nil
120
+ # TODO is this useable
121
+ def record_value #TODO test
122
+ if self.record
123
+ self.record.send(self.name.to_sym)
124
+ else
125
+ nil
126
+ end
127
+ end
128
+
129
+ private
130
+
131
+ def builder_local_variable_name
132
+ :field
113
133
  end
114
- end
115
134
 
116
- private
117
-
135
+ def set_default_values
136
+ self.title||=self.name.to_s.gsub("_", " ").capitalize
137
+ self.options||={}
138
+ end
118
139
 
119
- def set_default_values
120
- set_association
121
- set_type
122
- self.title||=self.name.to_s.capitalize
123
- self.options||={}
124
- end
140
+ def before_init *args
141
+ extract_args *args
142
+ set_name
143
+ if @name
144
+ process_type
145
+ end
146
+ end
125
147
 
126
- def set_type
127
- @type=@type.to_s.downcase if @type
128
- if @association
129
- @type="collection"
130
- elsif @type.nil? || @type.to_s=="object"
131
- @type=@@default_type
148
+ def process_type
149
+ set_association
150
+ set_type_from_args
151
+ set_type
132
152
  end
133
- end
134
153
 
135
- # Need here because this don't know how to recognize association.
136
- # TODO maybe need move to adapter, and it is converted there
137
- def set_association #TODO test
138
- assoc_name=@name.to_s.gsub(/_id$/,"")
139
- @association||=@dbi.reflect_on_association(assoc_name.to_sym) ||
140
- @dbi.reflect_on_association(assoc_name.pluralize.to_sym)
141
- end
154
+ def extract_args *args
155
+ if args
156
+ @given_args=args
157
+ @given_attributes=@given_args.extract_options!
158
+ else
159
+ @given_args=[]
160
+ @given_attributes={}
161
+ end
162
+ end
142
163
 
143
- def validate
144
- unless self.name
145
- raise Lolita::FieldNameError, "Field must have name."
164
+ def set_name
165
+ if @given_args.first
166
+ self.name=@given_args.first
167
+ else
168
+ self.name=@given_attributes[:name]
169
+ end
170
+ end
171
+
172
+ def set_type_from_args
173
+ self.type=@given_args[1] if @given_args[1]
174
+ end
175
+
176
+ def set_type
177
+ if !@type
178
+ if @association
179
+ self.type="array"
180
+ elsif dbi_field=self.dbi.fields.detect{|f| f[:name].to_s==@name.to_s}
181
+ self.type=dbi_field[:type]
182
+ self.options=dbi_field[:options]
183
+ end
184
+ end
185
+ if @type.nil? || @type.to_s.downcase=="object"
186
+ self.type=@@default_type
187
+ end
188
+ end
189
+
190
+ # Need here because this don't know how to recognize association.
191
+ # TODO maybe need move to adapter, and it is converted there
192
+ def set_association #TODO test
193
+ assoc_name=@name.to_s.gsub(/_id$/,"")
194
+ @association||=@dbi.reflect_on_association(assoc_name.to_sym) ||
195
+ @dbi.reflect_on_association(assoc_name.pluralize.to_sym)
196
+ end
197
+
198
+ def validate
199
+ unless self.name
200
+ raise Lolita::FieldNameError, "Field must have name."
201
+ end
202
+ #FIXME need this validation
203
+ # if !@value && !@dbi.klass.instance_methods.include?(self.name.to_s)
204
+ # raise Lolita::FieldNameError, "#{@dbi.klass} must respond to #{self.name} method."
205
+ # end
146
206
  end
147
- #FIXME need this validation
148
- # if !@value && !@dbi.klass.instance_methods.include?(self.name.to_s)
149
- # raise Lolita::FieldNameError, "#{@dbi.klass} must respond to #{self.name} method."
150
- # end
207
+
151
208
  end
152
-
153
209
  end
154
210
  end
155
211
  end
@@ -0,0 +1,74 @@
1
+ module Lolita
2
+ module Configuration
3
+ module Field
4
+ class Array < Lolita::Configuration::Field::Base
5
+ lolita_accessor :conditions,:text_method,:value_method,:find_options,:association_type,:include_blank
6
+
7
+ def initialize *args,&block
8
+ @type="array"
9
+ self.builder="select"
10
+ @include_blank=true
11
+ super
12
+ set_association_type
13
+ end
14
+
15
+ def options_for_select=(value=nil)
16
+ @options_for_select=value
17
+ end
18
+
19
+ def options_for_select value=nil, &block
20
+ @options_for_select=value || block if value || block_given?
21
+ @options_for_select
22
+ end
23
+
24
+ # Collect values for array type field.
25
+ # Uses <code>text_method</code> for content. By default it search for
26
+ # first _String_ type field in DB. Uses <code>value_method</code> for value,
27
+ # by default it it is <code>id</code>. Use <code>conditions</code> or
28
+ # <code>find_options</code> for advanced search. When <code>find_options</code>
29
+ # is used, than <code>conditions</code> is ignored.
30
+ def association_values() #TODO test
31
+ @association_values||=if options_for_select
32
+ options_for_select
33
+ elsif @association
34
+ klass=@dbi.association_class_name(@association).camelize.constantize
35
+ current_text_method=@text_method || default_text_method(klass)
36
+ current_value_method=@value_method || :id
37
+ options=@find_options || {}
38
+ options[:conditions]||=@conditions
39
+
40
+ klass.find(:all,options).map{|r|
41
+ [r.send(current_text_method),r.send(current_value_method)]
42
+ }
43
+ else
44
+ []
45
+ end
46
+ @association_values
47
+ end
48
+
49
+ private
50
+
51
+ def set_association_type #TODO test
52
+ if @association
53
+ @association_type||=(@dbi.association_macro(@association) || :one)
54
+ else
55
+ @association_type||=:one
56
+ end
57
+ end
58
+
59
+ def default_text_method(klass)
60
+ assoc_dbi=Lolita::DBI::Base.new(klass)
61
+ field=assoc_dbi.fields.detect{|f| f[:type].downcase=="string"}
62
+ if field
63
+ field[:name]
64
+ else
65
+ raise Lolita::FieldTypeError, %^
66
+ Can't find any content field in #{assoc_dbi.klass}.
67
+ Use text_method in #{klass} to set one.
68
+ ^
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,12 @@
1
+ module Lolita
2
+ module Configuration
3
+ module Field
4
+ class BigDecimal < Lolita::Configuration::Field::Base
5
+ def initialize *args, &block
6
+ @type="big_decimal"
7
+ super
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -1,10 +1,12 @@
1
1
  module Lolita
2
2
  module Configuration
3
- class BooleanField < Lolita::Configuration::Field
4
- def initialize *args
5
- @type="boolean"
6
- super
3
+ module Field
4
+ class Boolean < Lolita::Configuration::Field::Base
5
+ def initialize *args
6
+ @type="boolean"
7
+ super
8
+ end
7
9
  end
8
10
  end
9
11
  end
10
- end
12
+ end
@@ -0,0 +1,13 @@
1
+ module Lolita
2
+ module Configuration
3
+ module Field
4
+ class Datetime < Lolita::Configuration::Field::Base
5
+ attr_accessor :format
6
+ def initialize *args
7
+ @type="date"
8
+ super
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,10 +1,12 @@
1
1
  module Lolita
2
2
  module Configuration
3
- class IntegerField < Lolita::Configuration::Field
4
- def initialize *args
5
- @type="integer"
6
- super
3
+ module Field
4
+ class Integer < Lolita::Configuration::Field::Base
5
+ def initialize *args
6
+ @type="integer"
7
+ super
8
+ end
7
9
  end
8
10
  end
9
11
  end
10
- end
12
+ end