dry_crud 1.2.7 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +60 -27
- data/Rakefile +3 -1
- data/VERSION +1 -1
- data/lib/generators/dry_crud/dry_crud_generator.rb +3 -3
- data/lib/generators/dry_crud/templates/INSTALL +3 -1
- data/lib/generators/dry_crud/templates/app/controllers/crud_controller.rb +106 -90
- data/lib/generators/dry_crud/templates/app/controllers/list_controller.rb +90 -74
- data/lib/generators/dry_crud/templates/app/controllers/render_inheritable.rb +34 -33
- data/lib/generators/dry_crud/templates/app/helpers/crud_helper.rb +39 -23
- data/lib/generators/dry_crud/templates/app/helpers/list_helper.rb +11 -9
- data/lib/generators/dry_crud/templates/app/helpers/standard_form_builder.rb +55 -47
- data/lib/generators/dry_crud/templates/app/helpers/standard_helper.rb +134 -86
- data/lib/generators/dry_crud/templates/app/helpers/standard_table_builder.rb +41 -35
- data/lib/generators/dry_crud/templates/app/views/crud/_actions_edit.html.erb +1 -0
- data/lib/generators/dry_crud/templates/app/views/crud/edit.html.erb +3 -3
- data/lib/generators/dry_crud/templates/app/views/crud/new.html.erb +2 -2
- data/lib/generators/dry_crud/templates/app/views/crud/show.html.erb +3 -3
- data/lib/generators/dry_crud/templates/app/views/layouts/crud.html.erb +9 -7
- data/lib/generators/dry_crud/templates/app/views/list/_search.html.erb +1 -1
- data/lib/generators/dry_crud/templates/app/views/list/index.html.erb +4 -4
- data/lib/generators/dry_crud/templates/app/views/shared/_error_messages.html.erb +3 -1
- data/lib/generators/dry_crud/templates/config/locales/en_crud.yml +63 -0
- data/lib/generators/dry_crud/templates/test/crud_test_model.rb +93 -58
- data/lib/generators/dry_crud/templates/test/custom_assertions.rb +24 -13
- data/lib/generators/dry_crud/templates/test/functional/crud_controller_test_helper.rb +26 -56
- data/lib/generators/dry_crud/templates/test/functional/crud_test_models_controller_test.rb +47 -41
- data/lib/generators/dry_crud/templates/test/unit/custom_assertions_test.rb +28 -24
- data/lib/generators/dry_crud/templates/test/unit/helpers/crud_helper_test.rb +20 -34
- data/lib/generators/dry_crud/templates/test/unit/helpers/list_helper_test.rb +39 -53
- data/lib/generators/dry_crud/templates/test/unit/helpers/render_inheritable_test.rb +33 -33
- data/lib/generators/dry_crud/templates/test/unit/helpers/standard_form_builder_test.rb +27 -27
- data/lib/generators/dry_crud/templates/test/unit/helpers/standard_helper_test.rb +103 -50
- data/lib/generators/dry_crud/templates/test/unit/helpers/standard_table_builder_test.rb +52 -24
- data/test/templates/Gemfile +34 -0
- data/test/templates/app/controllers/ajax_controller.rb +3 -3
- data/test/templates/app/controllers/application_controller.rb +1 -1
- data/test/templates/app/controllers/cities_controller.rb +2 -5
- data/test/templates/app/controllers/people_controller.rb +5 -5
- data/test/templates/app/controllers/vips_controller.rb +6 -11
- data/test/templates/app/helpers/people_helper.rb +2 -2
- data/test/templates/app/models/city.rb +9 -9
- data/test/templates/app/models/person.rb +5 -4
- data/test/templates/app/views/ajax/_actions_index.html.erb +2 -2
- data/test/templates/app/views/cities/_form.html.erb +5 -1
- data/test/templates/app/views/layouts/_menu.html.erb +3 -3
- data/test/templates/app/views/people/_attrs.html.erb +3 -3
- data/test/templates/config/database.yml +22 -0
- data/test/templates/config/locales/en_cities.yml +56 -0
- data/test/templates/config/routes.rb +5 -5
- data/test/templates/db/migrate/20100511174904_create_people_and_cities.rb +5 -2
- data/test/templates/db/seeds.rb +38 -29
- data/test/templates/test/functional/cities_controller_test.rb +12 -12
- data/test/templates/test/functional/people_controller_test.rb +10 -10
- metadata +11 -7
@@ -1,56 +1,72 @@
|
|
1
|
-
# Extension of StandardHelper functionality to provide a set of default
|
1
|
+
# Extension of StandardHelper functionality to provide a set of default
|
2
2
|
# attributes for the current model to be used in tables and forms. This helper
|
3
3
|
# is included in CrudController.
|
4
4
|
module CrudHelper
|
5
5
|
|
6
|
-
# Renders a generic form for the current entry with :default_attrs or the
|
7
|
-
# given attribute array, using the StandardFormBuilder.
|
6
|
+
# Renders a generic form for the current entry with :default_attrs or the
|
7
|
+
# given attribute array, using the StandardFormBuilder. An options hash
|
8
|
+
# may be given as the last argument.
|
8
9
|
# If a block is given, a custom form may be rendered and attrs is ignored.
|
9
|
-
def crud_form(attrs
|
10
|
-
attrs = default_attrs - [:created_at, :updated_at]
|
11
|
-
standard_form(@entry, attrs, &block)
|
10
|
+
def crud_form(*attrs, &block)
|
11
|
+
attrs = attrs_or_default(attrs) { default_attrs - [:created_at, :updated_at] }
|
12
|
+
standard_form(@entry, *attrs, &block)
|
12
13
|
end
|
13
|
-
|
14
|
-
# Create a table of the @entries variable with the default or
|
15
|
-
# the passed attributes in its columns.
|
14
|
+
|
15
|
+
# Create a table of the @entries variable with the default or
|
16
|
+
# the passed attributes in its columns. An options hash may be given
|
17
|
+
# as the last argument.
|
16
18
|
def crud_table(*attrs, &block)
|
17
19
|
if block_given?
|
18
20
|
list_table(*attrs, &block)
|
19
|
-
else
|
20
|
-
attrs = default_attrs
|
21
|
-
list_table(*attrs) do |t|
|
21
|
+
else
|
22
|
+
attrs = attrs_or_default(attrs) { default_attrs }
|
23
|
+
list_table(*attrs) do |t|
|
22
24
|
add_table_actions(t)
|
23
25
|
end
|
24
26
|
end
|
25
27
|
end
|
26
|
-
|
28
|
+
|
27
29
|
# Adds a set of standard action link column (show, edit, destroy) to the given table.
|
28
30
|
def add_table_actions(table)
|
29
31
|
action_col(table) { |e| link_table_action_show(e) }
|
30
32
|
action_col(table) { |e| link_table_action_edit(e) }
|
31
33
|
action_col(table) { |e| link_table_action_destroy(e) }
|
32
34
|
end
|
33
|
-
|
35
|
+
|
36
|
+
# Action link to show inside a table.
|
34
37
|
def link_table_action_show(record)
|
35
38
|
link_table_action('show', record)
|
36
39
|
end
|
37
|
-
|
40
|
+
|
41
|
+
# Action link to edit inside a table.
|
38
42
|
def link_table_action_edit(record)
|
39
|
-
link_table_action('edit', edit_polymorphic_path(record))
|
43
|
+
link_table_action('edit', edit_polymorphic_path(record))
|
40
44
|
end
|
41
|
-
|
45
|
+
|
46
|
+
# Action link to destroy inside a table.
|
42
47
|
def link_table_action_destroy(record)
|
43
|
-
link_table_action('delete', record,
|
44
|
-
:confirm =>
|
45
|
-
:method => :delete)
|
48
|
+
link_table_action('delete', record,
|
49
|
+
:confirm => ti(:confirm_delete),
|
50
|
+
:method => :delete)
|
46
51
|
end
|
47
|
-
|
52
|
+
|
53
|
+
# Generic action link inside a table.
|
48
54
|
def link_table_action(image, url, html_options = {})
|
49
|
-
link_to(action_icon(image), url, html_options)
|
55
|
+
link_to(action_icon(image), url, html_options)
|
50
56
|
end
|
51
|
-
|
57
|
+
|
58
|
+
# Defines a column with an action link.
|
52
59
|
def action_col(table, &block)
|
53
60
|
table.col('', :class => 'center', &block)
|
54
61
|
end
|
55
62
|
|
63
|
+
private
|
64
|
+
|
65
|
+
# Returns default attrs for a crud table if no others are passed.
|
66
|
+
def attrs_or_default(attrs)
|
67
|
+
options = attrs.extract_options!
|
68
|
+
attrs = yield if attrs.blank?
|
69
|
+
attrs << options
|
70
|
+
end
|
71
|
+
|
56
72
|
end
|
@@ -1,24 +1,26 @@
|
|
1
|
-
# Extension of StandardHelper functionality to provide a set of default
|
1
|
+
# Extension of StandardHelper functionality to provide a set of default
|
2
2
|
# attributes for the current model to be used in tables and forms. This helper
|
3
3
|
# is included in CrudController.
|
4
4
|
module ListHelper
|
5
|
-
|
6
|
-
# Create a table of the @entries variable with the default or
|
7
|
-
# the passed attributes in its columns.
|
5
|
+
|
6
|
+
# Create a table of the @entries variable with the default or
|
7
|
+
# the passed attributes in its columns. An options hash may be given
|
8
|
+
# as the last argument.
|
8
9
|
def list_table(*attrs, &block)
|
10
|
+
options = attrs.extract_options!
|
9
11
|
# only use default attrs if no attrs and no block are given
|
10
12
|
attributes = (block_given? || attrs.present?) ? attrs : default_attrs
|
11
|
-
table(@entries) do |t|
|
12
|
-
t.sortable_attrs(*attributes)
|
13
|
-
yield t if block_given?
|
13
|
+
table(@entries, options) do |t|
|
14
|
+
t.sortable_attrs(*attributes)
|
15
|
+
yield t if block_given?
|
14
16
|
end
|
15
17
|
end
|
16
|
-
|
18
|
+
|
17
19
|
# The default attributes to use in attrs, list and form partials.
|
18
20
|
# These are all defined attributes except certain special ones like 'id' or 'position'.
|
19
21
|
def default_attrs
|
20
22
|
attrs = model_class.column_names.collect(&:to_sym)
|
21
23
|
attrs - [:id, :position, :password]
|
22
24
|
end
|
23
|
-
|
25
|
+
|
24
26
|
end
|
@@ -1,23 +1,22 @@
|
|
1
1
|
# A form builder that automatically selects the corresponding input field
|
2
2
|
# for ActiveRecord column types. Convenience methods for each column type allow
|
3
|
-
# one to customize the different fields.
|
3
|
+
# one to customize the different fields.
|
4
4
|
# All field methods may be prefixed with 'labeled_' in order to render
|
5
5
|
# a standard label with them.
|
6
6
|
class StandardFormBuilder < ActionView::Helpers::FormBuilder
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
delegate :association, :column_type, :column_property, :captionize,
|
7
|
+
|
8
|
+
REQUIRED_MARK = '<span class="required">*</span>'.html_safe
|
9
|
+
|
10
|
+
attr_reader :template
|
11
|
+
|
12
|
+
delegate :association, :column_type, :column_property, :captionize, :ta,
|
14
13
|
:to => :template
|
15
|
-
|
14
|
+
|
16
15
|
# Render multiple input fields together with a label for the given attributes.
|
17
16
|
def labeled_input_fields(*attrs)
|
18
17
|
attrs.collect {|a| labeled_input_field(a) }.join("\n").html_safe
|
19
18
|
end
|
20
|
-
|
19
|
+
|
21
20
|
# Render a standartized label.
|
22
21
|
def label(attr, text = nil, options = {})
|
23
22
|
if attr.is_a?(Symbol) && text.nil? && options.blank?
|
@@ -26,7 +25,7 @@ class StandardFormBuilder < ActionView::Helpers::FormBuilder
|
|
26
25
|
super(attr, text, options)
|
27
26
|
end
|
28
27
|
end
|
29
|
-
|
28
|
+
|
30
29
|
# Render a corresponding input field for the given attribute.
|
31
30
|
# The input field is chosen based on the ActiveRecord column type.
|
32
31
|
# Use additional html_options for the input element.
|
@@ -47,58 +46,68 @@ class StandardFormBuilder < ActionView::Helpers::FormBuilder
|
|
47
46
|
end
|
48
47
|
end
|
49
48
|
end
|
50
|
-
|
49
|
+
|
51
50
|
# Render a standard text field.
|
52
51
|
def text_field(attr, html_options = {})
|
53
52
|
super(attr, {:size => 30}.merge(html_options))
|
54
53
|
end
|
55
|
-
|
54
|
+
|
56
55
|
# Render a standard password field.
|
57
56
|
def password_field(attr, html_options = {})
|
58
57
|
super(attr, {:size => 30}.merge(html_options))
|
59
58
|
end
|
60
|
-
|
59
|
+
|
61
60
|
# Render a standard text area.
|
62
61
|
def text_area(attr, html_options = {})
|
63
62
|
super(attr, {:rows => 5, :cols => 30}.merge(html_options))
|
64
63
|
end
|
65
|
-
|
64
|
+
|
66
65
|
# Render a standard string field with column contraints.
|
67
66
|
def string_field(attr, html_options = {})
|
68
67
|
limit = column_property(@object, attr, :limit)
|
69
68
|
html_options = {:maxlength => limit}.merge(html_options) if limit
|
70
69
|
text_field(attr, html_options)
|
71
70
|
end
|
72
|
-
|
71
|
+
|
73
72
|
# Render a standard number field.
|
74
73
|
def number_field(attr, html_options = {})
|
75
74
|
super(attr, {:size => 15}.merge(html_options))
|
76
75
|
end
|
77
|
-
|
76
|
+
|
78
77
|
# Render an integer field.
|
79
78
|
def integer_field(attr, html_options = {})
|
80
79
|
number_field(attr, html_options)
|
81
80
|
end
|
82
|
-
|
81
|
+
|
83
82
|
# Render a float field.
|
84
83
|
def float_field(attr, html_options = {})
|
85
84
|
number_field(attr, html_options)
|
86
|
-
end
|
87
|
-
|
85
|
+
end
|
86
|
+
|
88
87
|
# Render a decimal field.
|
89
88
|
def decimal_field(attr, html_options = {})
|
90
89
|
number_field(attr, html_options)
|
91
90
|
end
|
92
|
-
|
91
|
+
|
93
92
|
# Render a boolean field.
|
94
93
|
def boolean_field(attr, html_options = {})
|
95
94
|
check_box(attr, html_options)
|
96
95
|
end
|
97
|
-
|
96
|
+
|
98
97
|
# Render a field to select a date. You might want to customize this.
|
99
98
|
def date_field(attr, html_options = {})
|
100
99
|
date_select(attr, {}, html_options)
|
101
100
|
end
|
101
|
+
|
102
|
+
# Render a field to enter a time. You might want to customize this.
|
103
|
+
def time_field(attr, html_options = {})
|
104
|
+
time_select(attr, {}, html_options)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Render a field to enter a date and time. You might want to customize this.
|
108
|
+
def datetime_field(attr, html_options = {})
|
109
|
+
datetime_select(attr, {}, html_options)
|
110
|
+
end
|
102
111
|
|
103
112
|
# Render a select element for a :belongs_to association defined by attr.
|
104
113
|
# Use additional html_options for the select element.
|
@@ -107,38 +116,45 @@ class StandardFormBuilder < ActionView::Helpers::FormBuilder
|
|
107
116
|
def belongs_to_field(attr, html_options = {})
|
108
117
|
list = association_entries(attr, html_options)
|
109
118
|
if list.present?
|
110
|
-
collection_select(attr, list, :id, :
|
119
|
+
collection_select(attr, list, :id, :to_s, select_options(attr), html_options)
|
111
120
|
else
|
112
|
-
|
121
|
+
ta(:none_available, association(@object, attr))
|
113
122
|
end
|
114
123
|
end
|
115
|
-
|
124
|
+
|
116
125
|
# Renders a marker if the given attr has to be present.
|
117
126
|
def required_mark(attr)
|
118
127
|
required?(attr) ? REQUIRED_MARK : ''
|
119
128
|
end
|
120
|
-
|
129
|
+
|
121
130
|
# Render a label for the given attribute with the passed field html section.
|
122
131
|
def labeled(attr, field_html = nil, &block)
|
123
132
|
template.labeled(label(attr), field_html, &block)
|
124
133
|
end
|
134
|
+
|
135
|
+
# Depending if the given attribute must be present, return
|
136
|
+
# only an initial selection prompt or a blank option, respectively.
|
137
|
+
def select_options(attr)
|
138
|
+
assoc = association(@object, attr)
|
139
|
+
required?(attr) ? { :prompt => ta(:please_select, assoc) } :
|
140
|
+
{ :include_blank => ta(:no_entry, assoc) }
|
141
|
+
end
|
125
142
|
|
126
|
-
# Dispatch methods starting with 'labeled_' to render a label and the corresponding
|
143
|
+
# Dispatch methods starting with 'labeled_' to render a label and the corresponding
|
127
144
|
# input field. E.g. labeled_boolean_field(:checked, {:class => 'bold'})
|
128
145
|
def method_missing(name, *args)
|
129
146
|
if field_method = labeled_field_method?(name)
|
130
147
|
labeled(args.first, send(field_method, *args) + required_mark(args.first))
|
131
|
-
else
|
148
|
+
else
|
132
149
|
super(name, *args)
|
133
150
|
end
|
134
151
|
end
|
135
|
-
|
152
|
+
|
136
153
|
def respond_to?(name)
|
137
154
|
labeled_field_method?(name).present? || super(name)
|
138
155
|
end
|
139
|
-
|
140
156
|
protected
|
141
|
-
|
157
|
+
|
142
158
|
# Returns true if attr is a non-polymorphic belongs_to association,
|
143
159
|
# for which an input field may be automatically rendered.
|
144
160
|
def belongs_to_association?(attr, type)
|
@@ -149,41 +165,33 @@ class StandardFormBuilder < ActionView::Helpers::FormBuilder
|
|
149
165
|
false
|
150
166
|
end
|
151
167
|
end
|
152
|
-
|
168
|
+
|
153
169
|
# Returns the list of association entries, either from options[:list],
|
154
170
|
# the instance variable with the pluralized association name or all
|
155
171
|
# entries of the association klass.
|
156
172
|
def association_entries(attr, options)
|
157
|
-
list = options.delete(:list)
|
173
|
+
list = options.delete(:list)
|
158
174
|
unless list
|
159
175
|
assoc = association(@object, attr)
|
160
176
|
list = @template.send(:instance_variable_get, :"@#{assoc.name.to_s.pluralize}")
|
161
177
|
unless list
|
162
|
-
list = assoc.klass.
|
163
|
-
:order => assoc.options[:order])
|
178
|
+
list = assoc.klass.where(assoc.options[:conditions]).order(assoc.options[:order])
|
164
179
|
end
|
165
180
|
end
|
166
181
|
list
|
167
182
|
end
|
168
|
-
|
183
|
+
|
169
184
|
# Returns true if the given attribute must be present.
|
170
185
|
def required?(attr)
|
171
186
|
attr = attr.to_s
|
172
187
|
attr, attr_id = attr.end_with?('_id') ? [attr[0..-4], attr] : [attr, "#{attr}_id"]
|
173
|
-
validators = @object.class.validators_on(attr) +
|
188
|
+
validators = @object.class.validators_on(attr) +
|
174
189
|
@object.class.validators_on(attr_id)
|
175
190
|
validators.any? {|v| v.kind == :presence }
|
176
191
|
end
|
177
|
-
|
178
|
-
# Depending if the given attribute must be present, return
|
179
|
-
# only an initial selection prompt or a blank option, respectively.
|
180
|
-
def select_options(attr)
|
181
|
-
required?(attr) ? { :prompt => BLANK_SELECT_LABEL } :
|
182
|
-
{ :include_blank => StandardHelper::NO_ENTRY }
|
183
|
-
end
|
184
|
-
|
192
|
+
|
185
193
|
private
|
186
|
-
|
194
|
+
|
187
195
|
def labeled_field_method?(name)
|
188
196
|
prefix = 'labeled_'
|
189
197
|
if name.to_s.start_with?(prefix)
|
@@ -191,5 +199,5 @@ class StandardFormBuilder < ActionView::Helpers::FormBuilder
|
|
191
199
|
field_method if respond_to?(field_method)
|
192
200
|
end
|
193
201
|
end
|
194
|
-
|
202
|
+
|
195
203
|
end
|
@@ -1,36 +1,29 @@
|
|
1
|
-
# A view helper to standartize often used functions like formatting,
|
2
|
-
# tables, forms or action links. This helper is ideally defined in the
|
1
|
+
# A view helper to standartize often used functions like formatting,
|
2
|
+
# tables, forms or action links. This helper is ideally defined in the
|
3
3
|
# ApplicationController.
|
4
4
|
module StandardHelper
|
5
|
-
|
6
|
-
NO_LIST_ENTRIES_MESSAGE = "No entries found"
|
7
|
-
NO_ENTRY = '(none)'
|
8
|
-
CONFIRM_DELETE_MESSAGE = 'Do you really want to delete this entry?'
|
9
|
-
|
10
|
-
FLOAT_FORMAT = "%.2f"
|
11
|
-
TIME_FORMAT = "%H:%M"
|
5
|
+
|
12
6
|
EMPTY_STRING = " ".html_safe # non-breaking space asserts better css styling.
|
13
|
-
|
7
|
+
|
14
8
|
################ FORMATTING HELPERS ##################################
|
15
9
|
|
16
10
|
# Define an array of associations symbols in your helper that should not get automatically linked.
|
17
11
|
#def no_assoc_links = [:city]
|
18
|
-
|
12
|
+
|
19
13
|
# Formats a single value
|
20
14
|
def f(value)
|
21
15
|
case value
|
22
16
|
when Fixnum then number_with_delimiter(value)
|
23
|
-
when Float then
|
24
|
-
when Date then value
|
25
|
-
when Time then value
|
26
|
-
when true then
|
27
|
-
when false then
|
17
|
+
when Float then number_with_precision(value, :precision => 2)
|
18
|
+
when Date then l(value)
|
19
|
+
when Time then l(value, :format => :time)
|
20
|
+
when true then t(:"global.yes")
|
21
|
+
when false then t(:"global.no")
|
28
22
|
when nil then EMPTY_STRING
|
29
|
-
|
30
|
-
value.respond_to?(:label) ? value.label : value.to_s
|
23
|
+
else value.to_s
|
31
24
|
end
|
32
25
|
end
|
33
|
-
|
26
|
+
|
34
27
|
# Formats an arbitrary attribute of the given ActiveRecord object.
|
35
28
|
# If no specific format_{attr} method is found, formats the value as follows:
|
36
29
|
# If the value is an associated model, renders the label of this object.
|
@@ -45,150 +38,190 @@ module StandardHelper
|
|
45
38
|
format_type(obj, attr)
|
46
39
|
end
|
47
40
|
end
|
48
|
-
|
49
|
-
|
41
|
+
|
42
|
+
|
50
43
|
############## STANDARD HTML SECTIONS ############################
|
51
|
-
|
52
|
-
|
44
|
+
|
45
|
+
|
53
46
|
# Renders an arbitrary content with the given label. Used for uniform presentation.
|
54
47
|
def labeled(label, content = nil, &block)
|
55
48
|
content = capture(&block) if block_given?
|
56
|
-
render
|
57
|
-
:locals => { :label => label, :content => content})
|
49
|
+
render 'shared/labeled', :label => label, :content => content
|
58
50
|
end
|
59
|
-
|
51
|
+
|
60
52
|
# Transform the given text into a form as used by labels or table headers.
|
61
53
|
def captionize(text, clazz = nil)
|
62
54
|
if clazz.respond_to?(:human_attribute_name)
|
63
55
|
clazz.human_attribute_name(text)
|
64
56
|
else
|
65
|
-
text.to_s.humanize.titleize
|
57
|
+
text.to_s.humanize.titleize
|
66
58
|
end
|
67
59
|
end
|
68
|
-
|
69
|
-
# Renders a list of attributes with label and value for a given object.
|
60
|
+
|
61
|
+
# Renders a list of attributes with label and value for a given object.
|
70
62
|
# Optionally surrounded with a div.
|
71
63
|
def render_attrs(obj, *attrs)
|
72
|
-
attrs.collect do |a|
|
64
|
+
attrs.collect do |a|
|
73
65
|
labeled_attr(obj, a)
|
74
66
|
end.join("\n").html_safe
|
75
67
|
end
|
76
|
-
|
68
|
+
|
77
69
|
# Renders the formatted content of the given attribute with a label.
|
78
70
|
def labeled_attr(obj, attr)
|
79
71
|
labeled(captionize(attr, obj.class), format_attr(obj, attr))
|
80
72
|
end
|
81
|
-
|
82
|
-
# Renders a table for the given entries. One column is rendered for each attribute passed.
|
73
|
+
|
74
|
+
# Renders a table for the given entries. One column is rendered for each attribute passed.
|
83
75
|
# If a block is given, the columns defined therein are appended to the attribute columns.
|
84
76
|
# If entries is empty, an appropriate message is rendered.
|
77
|
+
# An options hash may be given as the last argument.
|
85
78
|
def table(entries, *attrs, &block)
|
86
79
|
if entries.present?
|
87
|
-
StandardTableBuilder.table(entries, self) do |t|
|
80
|
+
StandardTableBuilder.table(entries, self, attrs.extract_options!) do |t|
|
88
81
|
t.attrs(*attrs)
|
89
82
|
yield t if block_given?
|
90
83
|
end
|
91
84
|
else
|
92
|
-
content_tag(:div,
|
85
|
+
content_tag(:div, ti(:no_list_entries), :class => 'list')
|
93
86
|
end
|
94
87
|
end
|
95
|
-
|
88
|
+
|
96
89
|
# Renders a generic form for all given attributes using StandardFormBuilder.
|
97
90
|
# Before the input fields, the error messages are rendered, if present.
|
98
91
|
# The form is rendered with a basic save button.
|
99
92
|
# If a block is given, custom input fields may be rendered and attrs is ignored.
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
content << if block_given?
|
106
|
-
capture(form, &block)
|
93
|
+
# An options hash may be given as the last argument.
|
94
|
+
def standard_form(object, *attrs, &block)
|
95
|
+
form_for(object, {:builder => StandardFormBuilder}.merge(attrs.extract_options!)) do |form|
|
96
|
+
content = render('shared/error_messages', :errors => object.errors, :object => object)
|
97
|
+
|
98
|
+
content << if block_given?
|
99
|
+
capture(form, &block)
|
107
100
|
else
|
108
101
|
form.labeled_input_fields(*attrs)
|
109
102
|
end
|
110
|
-
|
111
|
-
content << labeled(nil, form.submit("
|
103
|
+
|
104
|
+
content << labeled(nil, form.submit(ti(:"button.save")) + cancel_link(object))
|
112
105
|
content.html_safe
|
113
106
|
end
|
114
107
|
end
|
115
|
-
|
108
|
+
|
116
109
|
def cancel_link(object)
|
117
|
-
link_to("
|
110
|
+
link_to(ti(:"button.cancel"), polymorphic_path(object), :class => 'cancel')
|
118
111
|
end
|
119
|
-
|
112
|
+
|
120
113
|
# Alternate table row
|
121
114
|
def tr_alt(cycle_name = 'row_class', &block)
|
122
115
|
content_tag(:tr, :class => cycle("even", "odd", :name => cycle_name), &block)
|
123
116
|
end
|
124
117
|
|
118
|
+
# Renders a div with clear:both style.
|
125
119
|
def clear
|
126
120
|
content_tag(:div, '', :class => 'clear')
|
127
121
|
end
|
128
|
-
|
129
|
-
|
122
|
+
|
123
|
+
|
130
124
|
######## ACTION LINKS ###################################################### :nodoc:
|
131
|
-
|
125
|
+
|
132
126
|
# Standard link action to the show page of a given record.
|
133
127
|
def link_action_show(record)
|
134
|
-
link_action
|
128
|
+
link_action ti(:"link.show"), 'show', record
|
135
129
|
end
|
136
|
-
|
130
|
+
|
137
131
|
# Standard link action to the edit page of a given record.
|
138
132
|
def link_action_edit(record)
|
139
|
-
link_action
|
133
|
+
link_action ti(:"link.edit"), 'edit', edit_polymorphic_path(record)
|
140
134
|
end
|
141
|
-
|
135
|
+
|
142
136
|
# Standard link action to the destroy action of a given record.
|
143
137
|
def link_action_destroy(record)
|
144
|
-
link_action
|
145
|
-
:confirm =>
|
138
|
+
link_action ti(:"link.delete"), 'delete', record,
|
139
|
+
:confirm => ti(:confirm_delete),
|
146
140
|
:method => :delete
|
147
141
|
end
|
148
|
-
|
142
|
+
|
149
143
|
# Standard link action to the list page.
|
150
144
|
def link_action_index(url_options = {:action => 'index', :returning => true})
|
151
|
-
link_action
|
145
|
+
link_action ti(:"link.list"), 'list', url_options
|
152
146
|
end
|
153
|
-
|
147
|
+
|
154
148
|
# Standard link action to the new page.
|
155
149
|
def link_action_add(url_options = {:action => 'new'})
|
156
|
-
link_action
|
150
|
+
link_action ti(:"link.add"), 'add', url_options
|
157
151
|
end
|
158
|
-
|
152
|
+
|
159
153
|
# A generic helper method to create action links.
|
160
154
|
# These link could be styled to look like buttons, for example.
|
161
155
|
def link_action(label, icon = nil, url = {}, html_options = {})
|
162
|
-
link_to(icon ? action_icon(icon, label) : label,
|
163
|
-
url,
|
156
|
+
link_to(icon ? action_icon(icon, label) : label,
|
157
|
+
url,
|
164
158
|
{:class => 'action'}.merge(html_options))
|
165
159
|
end
|
166
|
-
|
160
|
+
|
161
|
+
# Outputs an icon for an action with an optional label.
|
167
162
|
def action_icon(icon, label = nil)
|
168
|
-
html = image_tag("actions/#{icon}.png", :size => '16x16')
|
163
|
+
html = image_tag("actions/#{icon}.png", :size => '16x16')
|
169
164
|
html << ' ' << label if label
|
170
165
|
html
|
171
166
|
end
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
#
|
176
|
-
|
177
|
-
#
|
178
|
-
|
179
|
-
|
180
|
-
|
167
|
+
|
168
|
+
# Translates the passed key by looking it up over the template lookup path
|
169
|
+
# (i.e., usually the controller hierarchy). The key is searched in the following
|
170
|
+
# order:
|
171
|
+
# - {controller}.{current_partial}.{key}
|
172
|
+
# - {controller}.{current_action}.{key}
|
173
|
+
# - {controller}.global.{key}
|
174
|
+
# - {parent_controller}.{current_partial}.{key}
|
175
|
+
# - {parent_controller}.{current_action}.{key}
|
176
|
+
# - {parent_controller}.global.{key}
|
177
|
+
# - ...
|
178
|
+
# - global.{key}
|
179
|
+
def translate_inheritable(key, variables = {})
|
180
|
+
defaults = []
|
181
|
+
if controller.class.respond_to?(:template_lookup_path)
|
182
|
+
partial = @_virtual_path ? @_virtual_path.gsub(%r{.*/_?}, "") : nil
|
183
|
+
controller.class.template_lookup_path.each do |folder|
|
184
|
+
defaults << :"#{folder}.#{partial}.#{key}" if partial
|
185
|
+
defaults << :"#{folder}.#{action_name}.#{key}"
|
186
|
+
defaults << :"#{folder}.global.#{key}"
|
187
|
+
end
|
181
188
|
else
|
182
|
-
|
189
|
+
defaults << :"#{controller_name}.#{action_name}.#{key}"
|
190
|
+
defaults << :"#{controller_name}.global.#{key}"
|
183
191
|
end
|
192
|
+
defaults << :"global.#{key}"
|
193
|
+
|
194
|
+
variables[:default] ||= defaults
|
195
|
+
t(defaults.shift, variables)
|
184
196
|
end
|
185
197
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
198
|
+
alias_method :ti, :translate_inheritable
|
199
|
+
|
200
|
+
# Translates the passed key for an active record association. This helper is used
|
201
|
+
# for rendering association dependent keys in forms like :no_entry, :none_available or
|
202
|
+
# :please_select.
|
203
|
+
# The key is looked up in the following order:
|
204
|
+
# - activerecord.associations.models.{model_name}.{association_name}.{key}
|
205
|
+
# - activerecord.associations.{association_model_name}.{key}
|
206
|
+
# - global.associations.{key}
|
207
|
+
def translate_association(key, assoc = nil, variables = {})
|
208
|
+
primary = if assoc
|
209
|
+
variables[:default] ||= [:"activerecord.associations.#{assoc.klass.name.underscore}.#{key}",
|
210
|
+
:"global.associations.#{key}"]
|
211
|
+
:"activerecord.associations.models.#{assoc.active_record.name.underscore}.#{assoc.name}.#{key}"
|
212
|
+
else
|
213
|
+
:"global.associations.#{key}"
|
214
|
+
end
|
215
|
+
t(primary, variables)
|
190
216
|
end
|
191
217
|
|
218
|
+
alias_method :ta, :translate_association
|
219
|
+
|
220
|
+
|
221
|
+
protected
|
222
|
+
|
223
|
+
# Helper methods that are not directly called from templates.
|
224
|
+
|
192
225
|
# Formats an arbitrary attribute of the given object depending on its data type.
|
193
226
|
# For ActiveRecords, take the defined data type into account for special types
|
194
227
|
# that have no own object class.
|
@@ -204,24 +237,39 @@ module StandardHelper
|
|
204
237
|
else f(val)
|
205
238
|
end
|
206
239
|
end
|
207
|
-
|
240
|
+
|
208
241
|
# Returns the ActiveRecord column type or nil.
|
209
242
|
def column_type(obj, attr)
|
210
243
|
column_property(obj, attr, :type)
|
211
244
|
end
|
212
|
-
|
245
|
+
|
213
246
|
# Returns an ActiveRecord column property for the passed attr or nil
|
214
247
|
def column_property(obj, attr, property)
|
215
248
|
if obj.respond_to?(:column_for_attribute)
|
216
249
|
column = obj.column_for_attribute(attr)
|
217
250
|
column.try(property)
|
218
|
-
end
|
251
|
+
end
|
219
252
|
end
|
220
|
-
|
253
|
+
|
254
|
+
# Formats an active record association
|
255
|
+
def format_assoc(obj, assoc)
|
256
|
+
if assoc_val = obj.send(assoc.name)
|
257
|
+
link_to_unless(no_assoc_link?(assoc, assoc_val), assoc_val, assoc_val)
|
258
|
+
else
|
259
|
+
ta(:no_entry, assoc)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
# Returns true if no link should be created when formatting the given association.
|
264
|
+
def no_assoc_link?(assoc, val)
|
265
|
+
(respond_to?(:no_assoc_links) && no_assoc_links.to_a.include?(assoc.name.to_sym)) ||
|
266
|
+
!respond_to?("#{val.class.name.underscore}_path".to_sym)
|
267
|
+
end
|
268
|
+
|
221
269
|
# Returns the association proxy for the given attribute. The attr parameter
|
222
270
|
# may be the _id column or the association name. If a macro (e.g. :belongs_to)
|
223
271
|
# is given, the association must be of this type, otherwise, any association
|
224
|
-
# is returned. Returns nil if no association (or not of the given macro) was
|
272
|
+
# is returned. Returns nil if no association (or not of the given macro) was
|
225
273
|
# found.
|
226
274
|
def association(obj, attr, macro = nil)
|
227
275
|
if obj.class.respond_to?(:reflect_on_association)
|
@@ -230,5 +278,5 @@ module StandardHelper
|
|
230
278
|
assoc if assoc && (macro.nil? || assoc.macro == macro)
|
231
279
|
end
|
232
280
|
end
|
233
|
-
|
281
|
+
|
234
282
|
end
|