dry_crud 1.5.0 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +24 -19
- data/Rakefile +12 -4
- data/VERSION +1 -1
- data/lib/generators/dry_crud/dry_crud_generator.rb +7 -7
- data/lib/generators/dry_crud/templates/app/assets/stylesheets/crud.scss +18 -7
- data/lib/generators/dry_crud/templates/app/assets/stylesheets/sample.scss +13 -18
- data/lib/generators/dry_crud/templates/app/controllers/crud_controller.rb +74 -87
- data/lib/generators/dry_crud/templates/app/controllers/list_controller.rb +95 -50
- data/lib/generators/dry_crud/templates/app/helpers/crud_helper.rb +11 -11
- data/lib/generators/dry_crud/templates/app/helpers/list_helper.rb +7 -7
- data/lib/generators/dry_crud/templates/app/helpers/standard_form_builder.rb +55 -27
- data/lib/generators/dry_crud/templates/app/helpers/standard_helper.rb +83 -30
- data/lib/generators/dry_crud/templates/app/helpers/standard_table_builder.rb +5 -13
- data/lib/generators/dry_crud/templates/app/views/layouts/_flash.html.erb +1 -4
- data/lib/generators/dry_crud/templates/app/views/layouts/_flash.html.haml +1 -3
- data/lib/generators/dry_crud/templates/app/views/layouts/_nav.html.erb +6 -6
- data/lib/generators/dry_crud/templates/app/views/layouts/_nav.html.haml +5 -3
- data/lib/generators/dry_crud/templates/app/views/layouts/crud.html.erb +13 -11
- data/lib/generators/dry_crud/templates/app/views/layouts/crud.html.haml +15 -15
- data/lib/generators/dry_crud/templates/app/views/shared/_error_messages.html.erb +10 -10
- data/lib/generators/dry_crud/templates/app/views/shared/_labeled.html.erb +2 -2
- data/lib/generators/dry_crud/templates/app/views/shared/_labeled.html.haml +2 -2
- data/lib/generators/dry_crud/templates/config/initializers/field_error_proc.rb +1 -0
- data/lib/generators/dry_crud/templates/config/locales/en_crud.yml +1 -0
- data/lib/generators/dry_crud/templates/test/crud_test_model.rb +72 -17
- data/lib/generators/dry_crud/templates/test/custom_assertions.rb +1 -1
- data/lib/generators/dry_crud/templates/test/functional/crud_controller_test_helper.rb +42 -26
- data/lib/generators/dry_crud/templates/test/functional/crud_test_models_controller_test.rb +135 -29
- data/lib/generators/dry_crud/templates/test/unit/custom_assertions_test.rb +4 -4
- data/lib/generators/dry_crud/templates/test/unit/helpers/crud_helper_test.rb +4 -2
- data/lib/generators/dry_crud/templates/test/unit/helpers/list_helper_test.rb +2 -0
- data/lib/generators/dry_crud/templates/test/unit/helpers/standard_form_builder_test.rb +94 -16
- data/lib/generators/dry_crud/templates/test/unit/helpers/standard_helper_test.rb +58 -18
- data/lib/generators/dry_crud/templates/test/unit/helpers/standard_table_builder_test.rb +4 -4
- data/test/templates/Gemfile +1 -0
- data/test/templates/app/controllers/admin/cities_controller.rb +0 -7
- data/test/templates/app/controllers/admin/countries_controller.rb +2 -3
- data/test/templates/app/controllers/ajax_controller.rb +2 -0
- data/test/templates/app/controllers/people_controller.rb +1 -1
- data/test/templates/app/models/city.rb +2 -0
- data/test/templates/app/models/country.rb +2 -0
- data/test/templates/app/models/person.rb +2 -0
- data/test/templates/app/views/admin/cities/_attrs.html.erb +1 -0
- data/test/templates/app/views/admin/cities/_attrs.html.haml +1 -0
- data/test/templates/app/views/admin/cities/_form.html.erb +7 -1
- data/test/templates/app/views/admin/cities/_form.html.haml +5 -1
- data/test/templates/app/views/admin/cities/_list.html.erb +1 -4
- data/test/templates/app/views/admin/cities/_list.html.haml +1 -3
- data/test/templates/app/views/ajax/_actions_show.html.erb +4 -0
- data/test/templates/app/views/ajax/_actions_show.html.haml +4 -0
- data/test/templates/app/views/ajax/_form.html.erb +2 -0
- data/test/templates/app/views/ajax/_form.html.haml +2 -0
- data/test/templates/app/views/ajax/edit.js.erb +1 -0
- data/test/templates/app/views/ajax/edit.js.haml +1 -0
- data/test/templates/app/views/ajax/show.js.erb +1 -0
- data/test/templates/app/views/ajax/show.js.haml +1 -0
- data/test/templates/app/views/ajax/update.js.erb +5 -0
- data/test/templates/app/views/ajax/update.js.haml +5 -0
- data/test/templates/app/views/layouts/_nav.html.erb +6 -0
- data/test/templates/app/views/layouts/_nav.html.haml +5 -0
- data/test/templates/app/views/layouts/bootstrap.html.erb +68 -0
- data/test/templates/app/views/layouts/bootstrap.html.haml +49 -0
- data/test/templates/app/views/people/_attrs.html.erb +2 -2
- data/test/templates/app/views/people/_attrs.html.haml +2 -2
- data/test/templates/config/routes.rb +5 -5
- data/test/templates/db/migrate/20100511174904_create_people_and_cities.rb +1 -1
- data/test/templates/db/seeds.rb +52 -52
- data/test/templates/test/functional/admin/cities_controller_test.rb +15 -15
- data/test/templates/test/functional/admin/countries_controller_test.rb +4 -5
- data/test/templates/test/functional/people_controller_test.rb +32 -4
- metadata +22 -9
- data/lib/generators/dry_crud/templates/app/views/layouts/_menu.html.erb +0 -3
- data/lib/generators/dry_crud/templates/app/views/layouts/_menu.html.haml +0 -3
- data/test/templates/app/views/layouts/_menu.html.erb +0 -3
- data/test/templates/app/views/layouts/_menu.html.haml +0 -3
@@ -22,7 +22,7 @@ module StandardHelper
|
|
22
22
|
end
|
23
23
|
|
24
24
|
# Formats an arbitrary attribute of the given ActiveRecord object.
|
25
|
-
# If no specific format_{type}_{attr} or format_{attr} method is found,
|
25
|
+
# If no specific format_{type}_{attr} or format_{attr} method is found,
|
26
26
|
# formats the value as follows:
|
27
27
|
# If the value is an associated model, renders the label of this object.
|
28
28
|
# Otherwise, calls format_type.
|
@@ -35,6 +35,8 @@ module StandardHelper
|
|
35
35
|
send(format_attr_method, obj)
|
36
36
|
elsif assoc = association(obj, attr, :belongs_to)
|
37
37
|
format_assoc(obj, assoc)
|
38
|
+
elsif assoc = association(obj, attr, :has_many, :has_and_belongs_to_many)
|
39
|
+
format_many_assoc(obj, assoc)
|
38
40
|
else
|
39
41
|
format_type(obj, attr)
|
40
42
|
end
|
@@ -52,17 +54,18 @@ module StandardHelper
|
|
52
54
|
|
53
55
|
# Transform the given text into a form as used by labels or table headers.
|
54
56
|
def captionize(text, clazz = nil)
|
57
|
+
text = text.to_s
|
55
58
|
if clazz.respond_to?(:human_attribute_name)
|
56
|
-
clazz.human_attribute_name(text)
|
59
|
+
clazz.human_attribute_name(text.end_with?('_ids') ? text[0..-5].pluralize : text)
|
57
60
|
else
|
58
|
-
text.
|
61
|
+
text.humanize.titleize
|
59
62
|
end
|
60
63
|
end
|
61
64
|
|
62
65
|
# Renders a list of attributes with label and value for a given object.
|
63
66
|
# Optionally surrounded with a div.
|
64
67
|
def render_attrs(obj, *attrs)
|
65
|
-
attrs
|
68
|
+
safe_join(attrs) { |a| labeled_attr(obj, a) }
|
66
69
|
end
|
67
70
|
|
68
71
|
# Renders the formatted content of the given attribute with a label.
|
@@ -95,7 +98,7 @@ module StandardHelper
|
|
95
98
|
options[:builder] ||= StandardFormBuilder
|
96
99
|
options[:html] ||= {}
|
97
100
|
add_css_class options[:html], 'form-horizontal'
|
98
|
-
|
101
|
+
|
99
102
|
form_for(object, options) do |form|
|
100
103
|
record = object.is_a?(Array) ? object.last : object
|
101
104
|
content = render('shared/error_messages', :errors => record.errors, :object => record)
|
@@ -106,19 +109,39 @@ module StandardHelper
|
|
106
109
|
form.labeled_input_fields(*attrs)
|
107
110
|
end
|
108
111
|
|
109
|
-
content << content_tag(:div,
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
112
|
+
content << content_tag(:div, :class => 'form-actions') do
|
113
|
+
form.button(ti(:"button.save"), :class => 'btn btn-primary') +
|
114
|
+
' ' +
|
115
|
+
cancel_link(object)
|
116
|
+
end
|
114
117
|
content.html_safe
|
115
118
|
end
|
116
119
|
end
|
117
120
|
|
118
121
|
def cancel_link(object)
|
119
|
-
link_to(ti(:"button.cancel"), polymorphic_path(object), :class => 'cancel')
|
122
|
+
link_to(ti(:"button.cancel"), polymorphic_path(object, :returning => true), :class => 'cancel')
|
123
|
+
end
|
124
|
+
|
125
|
+
# Renders a simple unordered list, which will
|
126
|
+
# simply render all passed items or yield them
|
127
|
+
# to your block.
|
128
|
+
def simple_list(items,ul_options={},&blk)
|
129
|
+
content_tag_nested(:ul, items, ul_options) do |item|
|
130
|
+
content_tag(:li, block_given? ? yield(item) : f(item))
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# render a content tag with the collected contents rendered
|
135
|
+
# by &block for each item in collection.
|
136
|
+
def content_tag_nested(tag, collection, options = {}, &block)
|
137
|
+
content_tag(tag, safe_join(collection, &block), options)
|
120
138
|
end
|
121
139
|
|
140
|
+
# Overridden method that takes a block that is executed for each item in array
|
141
|
+
# before appending the results.
|
142
|
+
def safe_join(array, sep = $,, &block)
|
143
|
+
super(block_given? ? array.collect(&block) : array, sep)
|
144
|
+
end
|
122
145
|
|
123
146
|
######## ACTION LINKS ###################################################### :nodoc:
|
124
147
|
|
@@ -136,8 +159,8 @@ module StandardHelper
|
|
136
159
|
html << ' ' << label if label
|
137
160
|
html
|
138
161
|
end
|
139
|
-
|
140
|
-
# Translates the passed key by looking it up over the controller hierarchy.
|
162
|
+
|
163
|
+
# Translates the passed key by looking it up over the controller hierarchy.
|
141
164
|
# The key is searched in the following order:
|
142
165
|
# - {controller}.{current_partial}.{key}
|
143
166
|
# - {controller}.{current_action}.{key}
|
@@ -161,15 +184,15 @@ module StandardHelper
|
|
161
184
|
current = current.superclass
|
162
185
|
end
|
163
186
|
defaults << :"global.#{key}"
|
164
|
-
|
187
|
+
|
165
188
|
variables[:default] ||= defaults
|
166
189
|
t(defaults.shift, variables)
|
167
190
|
end
|
168
|
-
|
191
|
+
|
169
192
|
alias_method :ti, :translate_inheritable
|
170
193
|
|
171
194
|
# Translates the passed key for an active record association. This helper is used
|
172
|
-
# for rendering association dependent keys in forms like :no_entry, :none_available or
|
195
|
+
# for rendering association dependent keys in forms like :no_entry, :none_available or
|
173
196
|
# :please_select.
|
174
197
|
# The key is looked up in the following order:
|
175
198
|
# - activerecord.associations.models.{model_name}.{association_name}.{key}
|
@@ -185,19 +208,19 @@ module StandardHelper
|
|
185
208
|
end
|
186
209
|
t(primary, variables)
|
187
210
|
end
|
188
|
-
|
211
|
+
|
189
212
|
alias_method :ta, :translate_association
|
190
|
-
|
191
|
-
|
213
|
+
|
214
|
+
|
192
215
|
# Returns the css class for the given flash level.
|
193
216
|
def flash_class(level)
|
194
217
|
case level
|
195
218
|
when :notice then 'success'
|
196
|
-
when :error then 'error'
|
197
219
|
when :alert then 'error'
|
220
|
+
else level.to_s
|
198
221
|
end
|
199
222
|
end
|
200
|
-
|
223
|
+
|
201
224
|
# Adds a class to the given options, even if there are already classes.
|
202
225
|
def add_css_class(options, classes)
|
203
226
|
if options[:class]
|
@@ -206,7 +229,7 @@ module StandardHelper
|
|
206
229
|
options[:class] = classes
|
207
230
|
end
|
208
231
|
end
|
209
|
-
|
232
|
+
|
210
233
|
protected
|
211
234
|
|
212
235
|
# Helper methods that are not directly called from templates.
|
@@ -220,7 +243,7 @@ module StandardHelper
|
|
220
243
|
case column_type(obj, attr)
|
221
244
|
when :time then f(val.to_time)
|
222
245
|
when :date then f(val.to_date)
|
223
|
-
when :datetime, :timestamp then "#{f(val.to_date)} #{f(val.
|
246
|
+
when :datetime, :timestamp then "#{f(val.to_date)} #{f(val.time)}"
|
224
247
|
when :text then val.present? ? simple_format(h(val)) : EMPTY_STRING
|
225
248
|
when :decimal then f(val.to_s.to_f)
|
226
249
|
else f(val)
|
@@ -240,15 +263,33 @@ module StandardHelper
|
|
240
263
|
end
|
241
264
|
end
|
242
265
|
|
243
|
-
# Formats an active record association
|
266
|
+
# Formats an active record belongs_to association
|
244
267
|
def format_assoc(obj, assoc)
|
245
|
-
if
|
246
|
-
|
268
|
+
if val = obj.send(assoc.name)
|
269
|
+
assoc_link(assoc, val)
|
270
|
+
else
|
271
|
+
ta(:no_entry, assoc)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
# Formats an active record has_and_belongs_to_many or
|
276
|
+
# has_many association.
|
277
|
+
def format_many_assoc(obj, assoc)
|
278
|
+
values = obj.send(assoc.name)
|
279
|
+
if values.size == 1
|
280
|
+
assoc_link(assoc, values.first)
|
281
|
+
elsif values.present?
|
282
|
+
simple_list(values) { |val| assoc_link(assoc, val) }
|
247
283
|
else
|
248
284
|
ta(:no_entry, assoc)
|
249
285
|
end
|
250
286
|
end
|
251
287
|
|
288
|
+
# Renders a link to the given association entry.
|
289
|
+
def assoc_link(assoc, val)
|
290
|
+
link_to_unless(no_assoc_link?(assoc, val), val.to_s, val)
|
291
|
+
end
|
292
|
+
|
252
293
|
# Returns true if no link should be created when formatting the given association.
|
253
294
|
def no_assoc_link?(assoc, val)
|
254
295
|
!respond_to?("#{val.class.model_name.underscore}_path".to_sym)
|
@@ -259,12 +300,24 @@ module StandardHelper
|
|
259
300
|
# is given, the association must be of this type, otherwise, any association
|
260
301
|
# is returned. Returns nil if no association (or not of the given macro) was
|
261
302
|
# found.
|
262
|
-
def association(obj, attr,
|
303
|
+
def association(obj, attr, *macros)
|
263
304
|
if obj.class.respond_to?(:reflect_on_association)
|
264
|
-
name = attr.
|
305
|
+
name = assoc_and_id_attr(attr).first.to_sym
|
265
306
|
assoc = obj.class.reflect_on_association(name)
|
266
|
-
assoc if assoc && (
|
307
|
+
assoc if assoc && (macros.blank? || macros.include?(assoc.macro))
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
# Returns the name of the attr and it's corresponding field
|
312
|
+
def assoc_and_id_attr(attr)
|
313
|
+
attr = attr.to_s
|
314
|
+
attr, attr_id = if attr.end_with?('_id')
|
315
|
+
[attr[0..-4], attr]
|
316
|
+
elsif attr.end_with?('_ids')
|
317
|
+
[attr[0..-5].pluralize, attr]
|
318
|
+
else
|
319
|
+
[attr, "#{attr}_id"]
|
267
320
|
end
|
268
321
|
end
|
269
322
|
|
270
|
-
end
|
323
|
+
end
|
@@ -11,7 +11,7 @@ class StandardTableBuilder
|
|
11
11
|
# Delegate called methods to template.
|
12
12
|
# including StandardHelper would lead to problems with indirectly called methods.
|
13
13
|
delegate :content_tag, :format_attr, :column_type, :association,
|
14
|
-
:captionize, :add_css_class, :to => :template
|
14
|
+
:captionize, :add_css_class, :content_tag_nested, :to => :template
|
15
15
|
|
16
16
|
def initialize(entries, template, options = {})
|
17
17
|
@entries = entries
|
@@ -57,8 +57,8 @@ class StandardTableBuilder
|
|
57
57
|
def to_html
|
58
58
|
add_css_class options, 'table'
|
59
59
|
content_tag :table, options do
|
60
|
-
content_tag(:thead, html_header) +
|
61
|
-
|
60
|
+
content_tag(:thead, html_header) +
|
61
|
+
content_tag_nested(:tbody, entries) { |e| html_row(e) }
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
@@ -81,24 +81,16 @@ class StandardTableBuilder
|
|
81
81
|
private
|
82
82
|
|
83
83
|
def html_header
|
84
|
-
|
85
|
-
safe_join(cols) { |c| c.html_header }
|
86
|
-
end
|
84
|
+
content_tag_nested(:tr, cols) { |c| c.html_header }
|
87
85
|
end
|
88
86
|
|
89
87
|
def html_row(entry)
|
90
|
-
|
91
|
-
safe_join(cols) { |c| c.html_cell(entry) }
|
92
|
-
end
|
88
|
+
content_tag_nested(:tr, cols) { |c| c.html_cell(entry) }
|
93
89
|
end
|
94
90
|
|
95
91
|
def entry_class
|
96
92
|
entries.first.class
|
97
93
|
end
|
98
|
-
|
99
|
-
def safe_join(collection, &block)
|
100
|
-
collection.collect(&block).join.html_safe
|
101
|
-
end
|
102
94
|
|
103
95
|
# Helper class to store column information.
|
104
96
|
class Col < Struct.new(:header, :html_options, :template, :block) #:nodoc:
|
@@ -1,6 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
<
|
4
|
-
|
5
|
-
|
6
|
-
</
|
1
|
+
<%= link_to 'MyApp', root_path, :class => 'brand' %>
|
2
|
+
<ul class="nav">
|
3
|
+
<li><%= link_to "Link1", "/path1" %></li>
|
4
|
+
<li><%= link_to "Link2", "/path2" %></li>
|
5
|
+
<li><%= link_to "Link3", "/path3" %></li>
|
6
|
+
</ul>
|
@@ -12,44 +12,46 @@
|
|
12
12
|
<![endif]-->
|
13
13
|
|
14
14
|
<%= stylesheet_link_tag 'application', :media => 'all' %>
|
15
|
-
|
15
|
+
|
16
16
|
<!-- fav and touch icons -->
|
17
17
|
<link href="images/favicon.ico" rel="shortcut icon">
|
18
18
|
<link href="images/apple-touch-icon.png" rel="apple-touch-icon">
|
19
19
|
<link href="images/apple-touch-icon-72x72.png" rel="apple-touch-icon" sizes="72x72">
|
20
20
|
<link href="images/apple-touch-icon-114x114.png" rel="apple-touch-icon" sizes="114x114">
|
21
|
-
|
21
|
+
|
22
22
|
<%= yield :head %>
|
23
23
|
</head>
|
24
24
|
<body>
|
25
|
-
|
25
|
+
|
26
26
|
|
27
27
|
<div class="container">
|
28
|
-
|
29
|
-
|
28
|
+
<div class="navbar">
|
29
|
+
<%= render 'layouts/nav' %>
|
30
|
+
</div>
|
31
|
+
|
30
32
|
<h1><%= @title %></h1>
|
31
33
|
|
32
34
|
<%= render :partial => 'layouts/flash', :collection => [:notice, :alert], :as => :level %>
|
33
35
|
|
34
36
|
<div class="actions btn-toolbar">
|
35
|
-
<div class="pull-left">
|
36
|
-
<%= yield :tools %>
|
37
|
-
</div>
|
38
37
|
<div class="pull-right">
|
39
38
|
<%= yield :actions %>
|
40
39
|
</div>
|
40
|
+
<div class="pull-left">
|
41
|
+
<%= yield :tools %>
|
42
|
+
</div>
|
41
43
|
</div>
|
42
44
|
|
43
45
|
<div id="content">
|
44
46
|
<%= yield %>
|
45
47
|
</div>
|
46
|
-
|
48
|
+
|
47
49
|
</div>
|
48
50
|
|
49
51
|
<footer>
|
50
|
-
<p>©
|
52
|
+
<p>© code!z <%= Time.zone.now.year %></p>
|
51
53
|
</footer>
|
52
|
-
|
54
|
+
|
53
55
|
<!-- Javascript placed at the end of the document so the pages load faster -->
|
54
56
|
<%= javascript_include_tag 'application' %>
|
55
57
|
<%= javascript_tag yield(:javascripts) if content_for?(:javascripts) %>
|
@@ -5,38 +5,38 @@
|
|
5
5
|
%meta{:charset => 'utf-8'}
|
6
6
|
%title= strip_tags(@title)
|
7
7
|
= csrf_meta_tag
|
8
|
-
|
8
|
+
|
9
9
|
<!-- HTML5 shim, for IE6-8 support of HTML elements -->
|
10
10
|
<!--[if lt IE 9]>
|
11
11
|
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js" type="text/javascript"></script>
|
12
12
|
<![endif]-->
|
13
|
-
|
13
|
+
|
14
14
|
= stylesheet_link_tag 'application', :media => 'all'
|
15
|
-
|
15
|
+
|
16
16
|
%link{:href => "images/favicon.ico", :rel => "shortcut icon"}
|
17
17
|
%link{:href => "images/apple-touch-icon.png", :rel => "apple-touch-icon"}
|
18
18
|
%link{:href => "images/apple-touch-icon-72x72.png", :rel => "apple-touch-icon", :sizes => "72x72"}
|
19
19
|
%link{:href => "images/apple-touch-icon-114x114.png", :rel => "apple-touch-icon", :sizes => "114x114"}
|
20
|
-
|
20
|
+
|
21
21
|
= yield :head
|
22
|
-
|
22
|
+
|
23
23
|
%body
|
24
24
|
.container
|
25
|
-
= render 'layouts/nav'
|
26
|
-
|
25
|
+
.navbar= render 'layouts/nav'
|
26
|
+
|
27
27
|
%h1= @title
|
28
|
-
|
28
|
+
|
29
29
|
= render :partial => 'layouts/flash', :collection => [:notice, :alert], :as => :level
|
30
|
-
|
31
|
-
.actions.btn-toolbar
|
32
|
-
.pull-left=yield :tools
|
30
|
+
|
31
|
+
.actions.btn-toolbar
|
33
32
|
.pull-right= yield :actions
|
34
|
-
|
33
|
+
.pull-left= yield :tools
|
34
|
+
|
35
35
|
#content= yield
|
36
|
-
|
36
|
+
|
37
37
|
%footer
|
38
38
|
%p
|
39
|
-
©
|
40
|
-
|
39
|
+
© code!z #{Time.zone.now.year}
|
40
|
+
|
41
41
|
= javascript_include_tag 'application'
|
42
42
|
= javascript_tag yield(:javascripts) if content_for?(:javascripts)
|
@@ -1,12 +1,12 @@
|
|
1
1
|
<% if errors.any? %>
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
2
|
+
<div id='error_explanation' class='alert alert-error'>
|
3
|
+
<h2>
|
4
|
+
<%= ti(:"errors.header", :count => errors.count, :model => object.to_s) %>
|
5
|
+
</h2>
|
6
|
+
<ul>
|
7
|
+
<% errors.full_messages.each do |msg| %>
|
8
|
+
<li><%= msg %></li>
|
9
|
+
<% end %>
|
10
|
+
</ul>
|
11
|
+
</div>
|
12
12
|
<% end -%>
|
@@ -1,4 +1,4 @@
|
|
1
1
|
<div class="labeled">
|
2
|
-
|
3
|
-
|
2
|
+
<label><%= label.presence || raw(StandardHelper::EMPTY_STRING) %></label>
|
3
|
+
<div class="value"><%= content.presence || raw(StandardHelper::EMPTY_STRING) %></div>
|
4
4
|
</div>
|
@@ -1,3 +1,3 @@
|
|
1
1
|
.labeled
|
2
|
-
|
3
|
-
|
2
|
+
%label= label.presence || raw(StandardHelper::EMPTY_STRING)
|
3
|
+
.value= content.presence || raw(StandardHelper::EMPTY_STRING)
|
@@ -0,0 +1 @@
|
|
1
|
+
ActionView::Base.field_error_proc = Proc.new {|html_tag, instance| html_tag }
|
@@ -1,7 +1,13 @@
|
|
1
1
|
# A dummy model used for general testing.
|
2
2
|
class CrudTestModel < ActiveRecord::Base #:nodoc:
|
3
3
|
|
4
|
+
attr_protected nil
|
5
|
+
|
4
6
|
belongs_to :companion, :class_name => 'CrudTestModel'
|
7
|
+
has_and_belongs_to_many :others, :class_name => 'OtherCrudTestModel'
|
8
|
+
has_many :mores, :class_name => 'OtherCrudTestModel', :foreign_key => :more_id
|
9
|
+
|
10
|
+
before_destroy :protect_if_companion
|
5
11
|
|
6
12
|
validates :name, :presence => true
|
7
13
|
validates :rating, :inclusion => { :in => 1..10 }
|
@@ -15,7 +21,28 @@ class CrudTestModel < ActiveRecord::Base #:nodoc:
|
|
15
21
|
def chatty
|
16
22
|
remarks.size
|
17
23
|
end
|
18
|
-
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def protect_if_companion
|
28
|
+
if companion.present?
|
29
|
+
errors.add(:base, 'Cannot destroy model with companion')
|
30
|
+
false
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
class OtherCrudTestModel < ActiveRecord::Base #:nodoc:
|
37
|
+
|
38
|
+
attr_protected nil
|
39
|
+
|
40
|
+
has_and_belongs_to_many :others, :class_name => 'CrudTestModel'
|
41
|
+
belongs_to :more, :foreign_key => :more_id, :class_name => 'CrudTestModel'
|
42
|
+
|
43
|
+
def to_s
|
44
|
+
name
|
45
|
+
end
|
19
46
|
end
|
20
47
|
|
21
48
|
# Controller for the dummy model.
|
@@ -27,6 +54,7 @@ class CrudTestModelsController < CrudController #:nodoc:
|
|
27
54
|
|
28
55
|
before_create :possibly_redirect
|
29
56
|
before_create :handle_name
|
57
|
+
before_destroy :handle_name
|
30
58
|
|
31
59
|
before_render_new :possibly_redirect
|
32
60
|
before_render_new :set_companions
|
@@ -39,10 +67,22 @@ class CrudTestModelsController < CrudController #:nodoc:
|
|
39
67
|
# don't use the standard layout as it may require different routes
|
40
68
|
# than just the test route for this controller
|
41
69
|
layout false
|
42
|
-
|
43
|
-
def
|
44
|
-
super do |
|
45
|
-
format.
|
70
|
+
|
71
|
+
def index
|
72
|
+
super do |format|
|
73
|
+
format.js { render :text => 'index js'}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def show
|
78
|
+
super do |format|
|
79
|
+
format.html { render :text => 'custom html' } if entry.name == 'BBBBB'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def create
|
84
|
+
super do |format|
|
85
|
+
flash[:notice] = 'model got created' if entry.persisted?
|
46
86
|
end
|
47
87
|
end
|
48
88
|
|
@@ -60,9 +100,9 @@ class CrudTestModelsController < CrudController #:nodoc:
|
|
60
100
|
|
61
101
|
# custom callback
|
62
102
|
def handle_name
|
63
|
-
if
|
64
|
-
flash[:
|
65
|
-
|
103
|
+
if entry.name == 'illegal'
|
104
|
+
flash[:alert] = "illegal name"
|
105
|
+
false
|
66
106
|
end
|
67
107
|
end
|
68
108
|
|
@@ -113,11 +153,11 @@ module CrudTestHelper
|
|
113
153
|
def model_class
|
114
154
|
CrudTestModel
|
115
155
|
end
|
116
|
-
|
156
|
+
|
117
157
|
def controller_name
|
118
158
|
'crud_test_models'
|
119
159
|
end
|
120
|
-
|
160
|
+
|
121
161
|
def action_name
|
122
162
|
'index'
|
123
163
|
end
|
@@ -125,7 +165,7 @@ module CrudTestHelper
|
|
125
165
|
def params
|
126
166
|
{}
|
127
167
|
end
|
128
|
-
|
168
|
+
|
129
169
|
def path_args(entry)
|
130
170
|
entry
|
131
171
|
end
|
@@ -133,11 +173,11 @@ module CrudTestHelper
|
|
133
173
|
def sortable?(attr)
|
134
174
|
true
|
135
175
|
end
|
136
|
-
|
176
|
+
|
137
177
|
def h(text)
|
138
178
|
ERB::Util.h(text)
|
139
179
|
end
|
140
|
-
|
180
|
+
|
141
181
|
protected
|
142
182
|
|
143
183
|
# Sets up the test database with a crud_test_models table.
|
@@ -162,6 +202,14 @@ module CrudTestHelper
|
|
162
202
|
t.timestamps
|
163
203
|
end
|
164
204
|
end
|
205
|
+
ActiveRecord::Base.connection.create_table :other_crud_test_models, :force => true do |t|
|
206
|
+
t.string :name, :null => false, :limit => 50
|
207
|
+
t.integer :more_id
|
208
|
+
end
|
209
|
+
ActiveRecord::Base.connection.create_table :crud_test_models_other_crud_test_models, :force => true do |t|
|
210
|
+
t.belongs_to :crud_test_model
|
211
|
+
t.belongs_to :other_crud_test_model
|
212
|
+
end
|
165
213
|
|
166
214
|
CrudTestModel.reset_column_information
|
167
215
|
end
|
@@ -170,7 +218,7 @@ module CrudTestHelper
|
|
170
218
|
# Removes the crud_test_models table from the database.
|
171
219
|
def reset_db
|
172
220
|
c = ActiveRecord::Base.connection
|
173
|
-
[:crud_test_models].each do |table|
|
221
|
+
[:crud_test_models, :other_crud_test_models, :crud_test_models_other_crud_test_models].each do |table|
|
174
222
|
if c.table_exists?(table)
|
175
223
|
c.drop_table(table) rescue nil
|
176
224
|
end
|
@@ -180,6 +228,7 @@ module CrudTestHelper
|
|
180
228
|
# Creates 6 dummy entries for the crud_test_models table.
|
181
229
|
def create_test_data
|
182
230
|
(1..6).inject(nil) {|prev, i| create(i, prev) }
|
231
|
+
(1..6).each {|i| create_other(i) }
|
183
232
|
end
|
184
233
|
|
185
234
|
# Fixture-style accessor method to get CrudTestModel instances by name
|
@@ -207,14 +256,20 @@ module CrudTestHelper
|
|
207
256
|
:income => 10000000 * index + 0.1 * index,
|
208
257
|
:birthdate => "#{1900 + 10 * index}-#{index}-#{index}",
|
209
258
|
# store entire date to avoid time zone issues
|
210
|
-
:gets_up_at => RUBY_VERSION.include?('1.9.') ?
|
259
|
+
:gets_up_at => RUBY_VERSION.include?('1.9.') ?
|
211
260
|
Time.local(2000,1,1,index,index) :
|
212
|
-
Time.utc(2000,1,1,index,index),
|
261
|
+
Time.utc(2000,1,1,index,index),
|
213
262
|
:last_seen => "#{2000 + 10 * index}-#{index}-#{index} 1#{index}:2#{index}",
|
214
263
|
:human => index % 2 == 0,
|
215
264
|
:remarks => "#{c} #{str(index + 1)} #{str(index + 2)}\n" * (index % 3 + 1))
|
216
265
|
end
|
217
266
|
|
267
|
+
def create_other(index)
|
268
|
+
c = str(index)
|
269
|
+
others = CrudTestModel.all[index..(index+2)]
|
270
|
+
OtherCrudTestModel.create!(:name => c, :other_ids => others.collect(&:id), :more_id => others.first.try(:id))
|
271
|
+
end
|
272
|
+
|
218
273
|
def str(index)
|
219
274
|
(index + 64).chr * 5
|
220
275
|
end
|
@@ -233,5 +288,5 @@ module CrudTestHelper
|
|
233
288
|
|
234
289
|
c.execute("BEGIN") if start_transaction
|
235
290
|
end
|
236
|
-
|
291
|
+
|
237
292
|
end
|