active_scaffold 3.2.20 → 3.3.0.rc
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +19 -13
- data/README +66 -0
- data/app/assets/javascripts/jquery/active_scaffold.js +156 -113
- data/app/assets/javascripts/jquery/active_scaffold_chosen.js +11 -0
- data/app/assets/javascripts/jquery/date_picker_bridge.js.erb +0 -1
- data/app/assets/javascripts/jquery/jquery.editinplace.js +132 -128
- data/app/assets/javascripts/prototype/active_scaffold.js +68 -25
- data/{frontends/default/views/_horizontal_subform_footer.html.erb → app/assets/javascripts/prototype/active_scaffold_chosen.js} +0 -0
- data/app/assets/stylesheets/active_scaffold_colors.css.scss +8 -1
- data/app/assets/stylesheets/active_scaffold_layout.css +14 -8
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_add_existing_form.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_base_form.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_create_form.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_create_form_on_list.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_field_search.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_form.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_form_association.html.erb +8 -3
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_form_association_footer.html.erb +5 -4
- data/app/views/active_scaffold_overrides/_form_association_record.html.erb +85 -0
- data/app/views/active_scaffold_overrides/_form_attribute.html.erb +23 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_form_hidden_attribute.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_form_messages.html.erb +0 -0
- data/app/views/active_scaffold_overrides/_horizontal_subform.html.erb +12 -0
- data/app/views/active_scaffold_overrides/_horizontal_subform_footer.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_horizontal_subform_header.html.erb +3 -2
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_human_conditions.html.erb +0 -0
- data/app/views/active_scaffold_overrides/_list.html.erb +35 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_calculations.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_column_headings.html.erb +0 -0
- data/app/views/active_scaffold_overrides/_list_header.html.erb +8 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_inline_adapter.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_messages.html.erb +4 -4
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_pagination.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_pagination_links.html.erb +0 -0
- data/app/views/active_scaffold_overrides/_list_record.html.erb +30 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_list_with_header.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_messages.html.erb +0 -0
- data/app/views/active_scaffold_overrides/_refresh_list.js.erb +1 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_render_field.js.erb +9 -1
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_row.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_search.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_search_attribute.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_show.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_show_columns.html.erb +0 -0
- data/app/views/active_scaffold_overrides/_update_actions.html.erb +9 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_update_calculations.js.erb +0 -0
- data/app/views/active_scaffold_overrides/_update_column.js.erb +16 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_update_form.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/_update_messages.js.erb +0 -0
- data/app/views/active_scaffold_overrides/_vertical_subform.html.erb +8 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/action_confirmation.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/add_existing.js.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/add_existing_form.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/create.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/delete.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/destroy.js.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/edit_associated.js.erb +1 -1
- data/{frontends/default/views → app/views/active_scaffold_overrides}/field_search.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/form_messages.js.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/list.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/on_action_update.js.erb +3 -3
- data/{frontends/default/views → app/views/active_scaffold_overrides}/on_create.js.erb +1 -1
- data/{frontends/default/views → app/views/active_scaffold_overrides}/on_mark.js.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/on_update.js.erb +4 -4
- data/{frontends/default/views → app/views/active_scaffold_overrides}/render_field.js.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/row.js.erb +1 -1
- data/{frontends/default/views → app/views/active_scaffold_overrides}/search.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/show.html.erb +0 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/update.html.erb +1 -1
- data/app/views/active_scaffold_overrides/update_column.js.erb +26 -0
- data/{frontends/default/views → app/views/active_scaffold_overrides}/update_row.js.erb +0 -0
- data/config/locales/de.yml +1 -0
- data/config/locales/en.yml +1 -0
- data/config/locales/es.yml +1 -0
- data/config/locales/fr.yml +1 -0
- data/config/locales/hu.yml +1 -0
- data/config/locales/ja.yml +1 -0
- data/config/locales/ru.yml +1 -0
- data/lib/active_scaffold.rb +14 -26
- data/lib/active_scaffold/actions/core.rb +14 -11
- data/lib/active_scaffold/actions/create.rb +3 -3
- data/lib/active_scaffold/actions/delete.rb +3 -0
- data/lib/active_scaffold/actions/list.rb +9 -6
- data/lib/active_scaffold/actions/mark.rb +1 -1
- data/lib/active_scaffold/actions/nested.rb +8 -6
- data/lib/active_scaffold/actions/show.rb +6 -1
- data/lib/active_scaffold/actions/update.rb +39 -19
- data/lib/active_scaffold/active_record_permissions.rb +29 -12
- data/lib/active_scaffold/attribute_params.rb +14 -7
- data/lib/active_scaffold/bridges/calendar_date_select.rb +1 -1
- data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +1 -2
- data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/chosen.rb +14 -0
- data/lib/active_scaffold/bridges/chosen/helpers.rb +48 -0
- data/lib/active_scaffold/bridges/date_picker/helper.rb +7 -6
- data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +1 -1
- data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/file_column.rb +1 -1
- data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +1 -1
- data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +2 -2
- data/lib/active_scaffold/bridges/file_column/list_ui.rb +4 -4
- data/lib/active_scaffold/bridges/paperclip.rb +1 -1
- data/lib/active_scaffold/bridges/paperclip/form_ui.rb +1 -1
- data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/paperclip/paperclip_bridge_helpers.rb +1 -1
- data/lib/active_scaffold/bridges/shared/date_bridge.rb +1 -1
- data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +1 -1
- data/lib/active_scaffold/config/core.rb +9 -2
- data/lib/active_scaffold/config/list.rb +9 -13
- data/lib/active_scaffold/config/nested.rb +11 -2
- data/lib/active_scaffold/data_structures/action_columns.rb +19 -5
- data/lib/active_scaffold/data_structures/action_link.rb +9 -2
- data/lib/active_scaffold/data_structures/action_links.rb +5 -36
- data/lib/active_scaffold/data_structures/column.rb +21 -21
- data/lib/active_scaffold/data_structures/nested_info.rb +31 -44
- data/lib/active_scaffold/extensions/action_controller_rescueing.rb +1 -0
- data/lib/active_scaffold/extensions/action_view_rendering.rb +30 -36
- data/lib/active_scaffold/extensions/reverse_associations.rb +10 -6
- data/lib/active_scaffold/extensions/routing_mapper.rb +6 -5
- data/lib/active_scaffold/extensions/unsaved_associated.rb +1 -1
- data/lib/active_scaffold/finder.rb +18 -10
- data/lib/active_scaffold/helpers/association_helpers.rb +21 -2
- data/lib/active_scaffold/helpers/controller_helpers.rb +14 -16
- data/lib/active_scaffold/helpers/form_column_helpers.rb +161 -21
- data/lib/active_scaffold/helpers/id_helpers.rb +7 -7
- data/lib/active_scaffold/helpers/list_column_helpers.rb +42 -92
- data/lib/active_scaffold/helpers/search_column_helpers.rb +10 -3
- data/lib/active_scaffold/helpers/show_column_helpers.rb +4 -9
- data/lib/active_scaffold/helpers/view_helpers.rb +278 -78
- data/lib/active_scaffold/version.rb +2 -2
- data/lib/generators/active_scaffold_controller/templates/controller.rb +1 -1
- data/test/bridges/paperclip_test.rb +2 -2
- data/vendor/assets/javascripts/jquery-ui-timepicker-addon.js +1882 -1276
- metadata +79 -80
- data/README.md +0 -67
- data/frontends/default/views/_action_group.html.erb +0 -24
- data/frontends/default/views/_form_attribute.html.erb +0 -23
- data/frontends/default/views/_horizontal_subform.html.erb +0 -22
- data/frontends/default/views/_horizontal_subform_record.html.erb +0 -43
- data/frontends/default/views/_list.html.erb +0 -18
- data/frontends/default/views/_list_actions.html.erb +0 -15
- data/frontends/default/views/_list_header.html.erb +0 -10
- data/frontends/default/views/_list_record.html.erb +0 -13
- data/frontends/default/views/_list_record_columns.html.erb +0 -8
- data/frontends/default/views/_refresh_list.js.erb +0 -1
- data/frontends/default/views/_update_actions.html.erb +0 -9
- data/frontends/default/views/_vertical_subform.html.erb +0 -12
- data/frontends/default/views/_vertical_subform_record.html.erb +0 -43
- data/frontends/default/views/refresh_list.js.erb +0 -2
- data/frontends/default/views/update_column.js.erb +0 -15
- data/lib/active_scaffold/extensions/active_record_offset.rb +0 -12
- data/lib/active_scaffold/extensions/nil_id_in_url_params.rb +0 -7
@@ -55,25 +55,25 @@ module ActiveScaffold::Actions
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def row_respond_to_js
|
58
|
-
render
|
58
|
+
render :action => 'row'
|
59
59
|
end
|
60
60
|
|
61
61
|
# The actual algorithm to prepare for the list view
|
62
|
-
def
|
62
|
+
def set_includes_for_columns(action = :list)
|
63
63
|
@cache_associations = true
|
64
|
-
includes_for_list_columns = active_scaffold_config.
|
64
|
+
includes_for_list_columns = active_scaffold_config.send(action).columns.collect{ |c| c.includes }.flatten.uniq.compact
|
65
65
|
self.active_scaffold_includes.concat includes_for_list_columns
|
66
66
|
end
|
67
67
|
|
68
68
|
def get_row
|
69
|
-
|
69
|
+
set_includes_for_columns
|
70
70
|
klass = beginning_of_chain.includes(active_scaffold_includes)
|
71
71
|
@record = find_if_allowed(params[:id], :read, klass)
|
72
72
|
end
|
73
73
|
|
74
74
|
# The actual algorithm to prepare for the list view
|
75
75
|
def do_list
|
76
|
-
|
76
|
+
set_includes_for_columns
|
77
77
|
|
78
78
|
options = { :sorting => active_scaffold_config.list.user.sorting,
|
79
79
|
:count_includes => active_scaffold_config.list.user.count_includes }
|
@@ -96,6 +96,7 @@ module ActiveScaffold::Actions
|
|
96
96
|
end
|
97
97
|
|
98
98
|
def do_refresh_list
|
99
|
+
params.delete(:id)
|
99
100
|
do_search if respond_to? :do_search
|
100
101
|
do_list
|
101
102
|
end
|
@@ -135,7 +136,9 @@ module ActiveScaffold::Actions
|
|
135
136
|
@action_link = active_scaffold_config.action_links[action_name]
|
136
137
|
if params[:id] && params[:id] && params[:id].to_i > 0
|
137
138
|
crud_type ||= (request.post? || request.put?) ? :update : :delete
|
138
|
-
|
139
|
+
set_includes_for_columns
|
140
|
+
klass = beginning_of_chain.includes(active_scaffold_includes)
|
141
|
+
@record = find_if_allowed(params[:id], crud_type, klass)
|
139
142
|
unless @record.nil?
|
140
143
|
yield @record
|
141
144
|
else
|
@@ -29,7 +29,7 @@ module ActiveScaffold::Actions
|
|
29
29
|
def mark_respond_to_js
|
30
30
|
if params[:id]
|
31
31
|
do_search if respond_to? :do_search
|
32
|
-
|
32
|
+
set_includes_for_columns if active_scaffold_config.actions.include? :list
|
33
33
|
@page = find_page(:pagination => active_scaffold_config.mark.mark_all_mode != :page)
|
34
34
|
render :action => 'on_mark'
|
35
35
|
else
|
@@ -37,7 +37,7 @@ module ActiveScaffold::Actions
|
|
37
37
|
else
|
38
38
|
as_(:nested_for_model, :nested_model => active_scaffold_config.list.label, :parent_model => nested_parent_record.to_label)
|
39
39
|
end
|
40
|
-
if nested.sorted?
|
40
|
+
if nested.sorted? && !active_scaffold_config.nested.ignore_order_from_association
|
41
41
|
active_scaffold_config.list.user.nested_default_sorting = {:table_name => active_scaffold_config.model.model_name, :default_sorting => nested.default_sorting}
|
42
42
|
end
|
43
43
|
end
|
@@ -73,16 +73,18 @@ module ActiveScaffold::Actions
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def beginning_of_chain
|
76
|
-
if nested? && nested.association
|
76
|
+
if nested? && nested.association
|
77
77
|
if nested.association.collection?
|
78
|
-
|
79
|
-
elsif nested.association.options[:through] # has_one :through doesn't need conditions
|
78
|
+
nested_parent_record.send(nested.association.name)
|
79
|
+
elsif nested.association.options[:through] || nested.child_association.nil? # has_one :through doesn't need conditions, and without child_association is not possible to add them
|
80
80
|
active_scaffold_config.model
|
81
81
|
elsif nested.child_association.belongs_to?
|
82
|
-
active_scaffold_config.model.where(nested.child_association.foreign_key =>
|
82
|
+
active_scaffold_config.model.where(nested.child_association.foreign_key => nested_parent_record)
|
83
|
+
elsif nested.association.belongs_to?
|
84
|
+
active_scaffold_config.model.joins(nested.child_association.name).where(nested.association.active_record.table_name => {nested.association.active_record.primary_key => nested_parent_record}).readonly(false)
|
83
85
|
end
|
84
86
|
elsif nested? && nested.scope
|
85
|
-
|
87
|
+
nested_parent_record.send(nested.scope)
|
86
88
|
else
|
87
89
|
active_scaffold_config.model
|
88
90
|
end
|
@@ -41,7 +41,9 @@ module ActiveScaffold::Actions
|
|
41
41
|
# A simple method to retrieve and prepare a record for showing.
|
42
42
|
# May be overridden to customize show routine
|
43
43
|
def do_show
|
44
|
-
|
44
|
+
set_includes_for_columns(:show) if active_scaffold_config.actions.include? :list
|
45
|
+
klass = beginning_of_chain.includes(active_scaffold_includes)
|
46
|
+
@record = find_if_allowed(params[:id], :read, klass)
|
45
47
|
end
|
46
48
|
|
47
49
|
# The default security delegates to ActiveRecordPermissions.
|
@@ -49,6 +51,9 @@ module ActiveScaffold::Actions
|
|
49
51
|
def show_authorized?(record = nil)
|
50
52
|
(record || self).send(:authorized_for?, :crud_type => :read)
|
51
53
|
end
|
54
|
+
def show_ignore?(record = nil)
|
55
|
+
!self.send(:authorized_for?, :crud_type => :read)
|
56
|
+
end
|
52
57
|
private
|
53
58
|
def show_authorized_filter
|
54
59
|
link = active_scaffold_config.show.link || active_scaffold_config.show.class.link
|
@@ -18,7 +18,7 @@ module ActiveScaffold::Actions
|
|
18
18
|
# for inline (inlist) editing
|
19
19
|
def update_column
|
20
20
|
do_update_column
|
21
|
-
@column_span_id = params
|
21
|
+
@column_span_id = params.delete(:editor_id) || params.delete(:editorId)
|
22
22
|
end
|
23
23
|
|
24
24
|
protected
|
@@ -35,7 +35,7 @@ module ActiveScaffold::Actions
|
|
35
35
|
def update_respond_to_html
|
36
36
|
if params[:iframe]=='true' # was this an iframe post ?
|
37
37
|
responds_to_parent do
|
38
|
-
render :action => 'on_update
|
38
|
+
render :action => 'on_update', :formats => [:js], :layout => false
|
39
39
|
end
|
40
40
|
else # just a regular post
|
41
41
|
if successful?
|
@@ -48,7 +48,13 @@ module ActiveScaffold::Actions
|
|
48
48
|
end
|
49
49
|
def update_respond_to_js
|
50
50
|
if successful?
|
51
|
-
|
51
|
+
if !render_parent? && active_scaffold_config.actions.include?(:list)
|
52
|
+
if update_refresh_list?
|
53
|
+
do_refresh_list
|
54
|
+
else
|
55
|
+
get_row
|
56
|
+
end
|
57
|
+
end
|
52
58
|
flash.now[:info] = as_(:updated_model, :model => @record.to_label) if active_scaffold_config.update.persistent
|
53
59
|
end
|
54
60
|
render :action => 'on_update'
|
@@ -62,6 +68,7 @@ module ActiveScaffold::Actions
|
|
62
68
|
def update_respond_to_yaml
|
63
69
|
render :text => Hash.from_xml(response_object.to_xml(:only => active_scaffold_config.update.columns.names)).to_yaml, :content_type => Mime::YAML, :status => response_status
|
64
70
|
end
|
71
|
+
|
65
72
|
# A simple method to find and prepare a record for editing
|
66
73
|
# May be overridden to customize the record (set default values, etc.)
|
67
74
|
def do_edit
|
@@ -81,7 +88,7 @@ module ActiveScaffold::Actions
|
|
81
88
|
active_scaffold_config.model.transaction do
|
82
89
|
@record = update_record_from_params(@record, active_scaffold_config.update.columns, attributes) unless options[:no_record_param_update]
|
83
90
|
before_update_save(@record)
|
84
|
-
self.successful = [@record.valid?, @record.associated_valid?].all?
|
91
|
+
self.successful = [@record.valid?, @record.associated_valid?].all? # this syntax avoids a short-circuit
|
85
92
|
if successful?
|
86
93
|
@record.save! and @record.save_associated!
|
87
94
|
after_update_save(@record)
|
@@ -104,23 +111,33 @@ module ActiveScaffold::Actions
|
|
104
111
|
end
|
105
112
|
|
106
113
|
def do_update_column
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
114
|
+
# delete from params so update :table won't break urls, also they shouldn't be used in sort links too
|
115
|
+
value = params.delete(:value)
|
116
|
+
column = params.delete(:column).to_sym
|
117
|
+
params.delete(:original_html)
|
118
|
+
params.delete(:original_value)
|
119
|
+
|
120
|
+
@record = find_if_allowed(params[:id], :read)
|
121
|
+
if @record.authorized_for?(:crud_type => :update, :column => column)
|
122
|
+
@column = active_scaffold_config.columns[column]
|
123
|
+
value ||= unless @column.column.nil? || @column.column.null
|
124
|
+
@column.column.default == true ? false : @column.column.default
|
116
125
|
end
|
117
|
-
unless column.nil?
|
118
|
-
|
119
|
-
|
126
|
+
unless @column.nil?
|
127
|
+
value = column_value_from_param_value(@record, @column, value)
|
128
|
+
value = [] if value.nil? && @column.form_ui && @column.plural_association?
|
120
129
|
end
|
121
|
-
@record.send("#{
|
130
|
+
@record.send("#{@column.name}=", value)
|
122
131
|
before_update_save(@record)
|
123
|
-
@record.save
|
132
|
+
self.successful = @record.save
|
133
|
+
if self.successful? && active_scaffold_config.actions.include?(:list)
|
134
|
+
if @column.inplace_edit_update == :table
|
135
|
+
params.delete(:id)
|
136
|
+
do_list
|
137
|
+
elsif @column.inplace_edit_update
|
138
|
+
get_row
|
139
|
+
end
|
140
|
+
end
|
124
141
|
after_update_save(@record)
|
125
142
|
end
|
126
143
|
end
|
@@ -139,7 +156,10 @@ module ActiveScaffold::Actions
|
|
139
156
|
# The default security delegates to ActiveRecordPermissions.
|
140
157
|
# You may override the method to customize.
|
141
158
|
def update_authorized?(record = nil)
|
142
|
-
(!nested? || !nested.readonly?) && (record || self).
|
159
|
+
(!nested? || !nested.readonly?) && (record || self).authorized_for?(:crud_type => :update)
|
160
|
+
end
|
161
|
+
def update_ignore?(record = nil)
|
162
|
+
!self.authorized_for?(:crud_type => :update)
|
143
163
|
end
|
144
164
|
private
|
145
165
|
def update_authorized_filter
|
@@ -65,6 +65,10 @@ module ActiveRecordPermissions
|
|
65
65
|
def self.included(base)
|
66
66
|
base.extend SecurityMethods
|
67
67
|
base.send :include, SecurityMethods
|
68
|
+
class << base
|
69
|
+
attr_accessor :class_security_methods
|
70
|
+
attr_accessor :instance_security_methods
|
71
|
+
end
|
68
72
|
end
|
69
73
|
|
70
74
|
# Because any class-level queries get delegated to the instance level via a new record,
|
@@ -85,34 +89,47 @@ module ActiveRecordPermissions
|
|
85
89
|
def authorized_for?(options = {})
|
86
90
|
raise ArgumentError, "unknown crud type #{options[:crud_type]}" if options[:crud_type] and ![:create, :read, :update, :delete].include?(options[:crud_type])
|
87
91
|
|
92
|
+
# collect other possibly-related methods that actually exist
|
93
|
+
methods = cached_authorized_for_methods(options)
|
94
|
+
return ActiveRecordPermissions.default_permission if methods.empty?
|
95
|
+
return send(methods.first) if methods.one?
|
96
|
+
|
97
|
+
# if any method returns false, then return false
|
98
|
+
return false if methods.any? {|m| !send(m)}
|
99
|
+
true
|
100
|
+
end
|
101
|
+
|
102
|
+
def cached_authorized_for_methods(options)
|
103
|
+
key = "#{options[:crud_type]}##{options[:column]}##{options[:action]}"
|
104
|
+
if self.is_a? Class
|
105
|
+
self.class_security_methods ||= {}
|
106
|
+
self.class_security_methods[key] ||= authorized_for_methods(options)
|
107
|
+
else
|
108
|
+
self.class.instance_security_methods ||= {}
|
109
|
+
self.class.instance_security_methods[key] ||= authorized_for_methods(options)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def authorized_for_methods(options)
|
88
114
|
# column_authorized_for_crud_type? has the highest priority over other methods,
|
89
115
|
# you can disable a crud verb and enable that verb for a column
|
90
116
|
# (for example, disable update and enable inplace_edit in a column)
|
91
117
|
method = column_and_crud_type_security_method(options[:column], options[:crud_type])
|
92
|
-
return
|
118
|
+
return [method] if method and respond_to?(method)
|
93
119
|
|
94
120
|
# authorized_for_action? has higher priority than other methods,
|
95
121
|
# you can disable a crud verb and enable an action with that crud verb
|
96
122
|
# (for example, disable update and enable an action with update as crud type)
|
97
123
|
method = action_security_method(options[:action])
|
98
|
-
return
|
124
|
+
return [method] if method and respond_to?(method)
|
99
125
|
|
100
126
|
# collect other possibly-related methods that actually exist
|
101
127
|
methods = [
|
102
128
|
column_security_method(options[:column]),
|
103
129
|
crud_type_security_method(options[:crud_type]),
|
104
130
|
].compact.select {|m| respond_to?(m)}
|
105
|
-
|
106
|
-
# if any method returns false, then return false
|
107
|
-
return false if methods.any? {|m| !send(m)}
|
108
|
-
|
109
|
-
# if any method actually exists then it must've returned true, so return true
|
110
|
-
return true unless methods.empty?
|
111
|
-
|
112
|
-
# if no method exists, return the default permission
|
113
|
-
return ActiveRecordPermissions.default_permission
|
114
131
|
end
|
115
|
-
|
132
|
+
|
116
133
|
private
|
117
134
|
|
118
135
|
def column_security_method(column)
|
@@ -66,7 +66,7 @@ module ActiveScaffold
|
|
66
66
|
if parent_record.new_record?
|
67
67
|
parent_record.class.reflect_on_all_associations.each do |a|
|
68
68
|
next unless [:has_one, :has_many].include?(a.macro) and not (a.options[:through] || a.options[:finder_sql])
|
69
|
-
next unless association_proxy = parent_record.send(a.name)
|
69
|
+
next unless (association_proxy = parent_record.send(a.name)).present?
|
70
70
|
|
71
71
|
raise ActiveScaffold::ReverseAssociationRequired, "Association #{a.name} in class #{parent_record.class.name}: In order to support :has_one and :has_many where the parent record is new and the child record(s) validate the presence of the parent, ActiveScaffold requires the reverse association (the belongs_to)." unless a.reverse
|
72
72
|
|
@@ -100,11 +100,18 @@ module ActiveScaffold
|
|
100
100
|
|
101
101
|
def column_value_from_param_simple_value(parent_record, column, value)
|
102
102
|
if column.singular_association?
|
103
|
-
|
104
|
-
|
103
|
+
if value.present?
|
104
|
+
if column.polymorphic_association?
|
105
|
+
class_name = parent_record.send(column.association.foreign_type)
|
106
|
+
class_name.constantize.find(value) if class_name
|
107
|
+
else
|
108
|
+
# it's a single id
|
109
|
+
column.association.klass.find(value)
|
110
|
+
end
|
111
|
+
end
|
105
112
|
elsif column.plural_association?
|
106
113
|
column_plural_assocation_value_from_value(column, Array(value))
|
107
|
-
elsif column.number? && [:i18n_number, :currency].include?(column.options[:format])
|
114
|
+
elsif column.number? && [:i18n_number, :currency].include?(column.options[:format]) && column.form_ui != :number
|
108
115
|
self.class.i18n_number_to_native_format(value)
|
109
116
|
else
|
110
117
|
# convert empty strings into nil. this works better with 'null => true' columns (and validations),
|
@@ -118,7 +125,7 @@ module ActiveScaffold
|
|
118
125
|
def column_plural_assocation_value_from_value(column, value)
|
119
126
|
# it's an array of ids
|
120
127
|
if value and not value.empty?
|
121
|
-
ids = value.select {|id| id.
|
128
|
+
ids = value.select {|id| id.present?}
|
122
129
|
ids.empty? ? [] : column.association.klass.find(ids)
|
123
130
|
end
|
124
131
|
end
|
@@ -137,7 +144,7 @@ module ActiveScaffold
|
|
137
144
|
manage_nested_record_from_params(parent_record, column, value)
|
138
145
|
elsif column.plural_association?
|
139
146
|
# HACK to be able to delete all associated records, hash will include "0" => ""
|
140
|
-
value.collect {|key, value| manage_nested_record_from_params(parent_record, column, value) unless value == ""}.compact
|
147
|
+
value.sort.collect {|key, value| manage_nested_record_from_params(parent_record, column, value) unless value == ""}.compact
|
141
148
|
else
|
142
149
|
value
|
143
150
|
end
|
@@ -190,7 +197,7 @@ module ActiveScaffold
|
|
190
197
|
if value.is_a?(Hash)
|
191
198
|
attributes_hash_is_empty?(value, klass)
|
192
199
|
elsif value.is_a?(Array)
|
193
|
-
value.
|
200
|
+
value.any? {|id| id.respond_to?(:empty?) ? !id.empty? : true}
|
194
201
|
else
|
195
202
|
value.respond_to?(:empty?) ? value.empty? : false
|
196
203
|
end
|
@@ -3,7 +3,7 @@ class ActiveScaffold::Bridges::CalendarDateSelect < ActiveScaffold::DataStructur
|
|
3
3
|
# check to see if the old bridge was installed. If so, warn them
|
4
4
|
# we can detect this by checking to see if the bridge was installed before calling this code
|
5
5
|
|
6
|
-
if ActiveScaffold::Config::Core.instance_methods.include?("initialize_with_calendar_date_select"
|
6
|
+
if ActiveScaffold::Config::Core.instance_methods.include?("initialize_with_calendar_date_select")
|
7
7
|
raise RuntimeError, "We've detected that you have active_scaffold_calendar_date_select_bridge installed. This plugin has been moved to core. Please remove active_scaffold_calendar_date_select_bridge to prevent any conflicts"
|
8
8
|
end
|
9
9
|
|
@@ -11,8 +11,7 @@ module CanCan
|
|
11
11
|
module Ability
|
12
12
|
def as_action_aliases
|
13
13
|
alias_action :list, :row, :show_search, :render_field, :to => :read
|
14
|
-
alias_action :update_column, :
|
15
|
-
:edit_associated, :new_existing, :add_existing, :to => :update
|
14
|
+
alias_action :update_column, :edit_associated, :new_existing, :add_existing, :to => :update
|
16
15
|
alias_action :delete, :destroy_existing, :to => :destroy
|
17
16
|
end
|
18
17
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module ActiveScaffold
|
2
2
|
module Helpers
|
3
3
|
module ListColumnHelpers
|
4
|
-
def active_scaffold_column_carrierwave(
|
4
|
+
def active_scaffold_column_carrierwave(record, column)
|
5
5
|
carrierwave = record.send("#{column.name}")
|
6
6
|
return nil unless !carrierwave.file.blank?
|
7
7
|
thumbnail_style = ActiveScaffold::Bridges::Carrierwave::CarrierwaveBridgeHelpers.thumbnail_style
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class ActiveScaffold::Bridges::Chosen < ActiveScaffold::DataStructures::Bridge
|
2
|
+
def self.install
|
3
|
+
require File.join(File.dirname(__FILE__), "chosen/helpers.rb")
|
4
|
+
end
|
5
|
+
def self.install?
|
6
|
+
super && [:jquery, :prototype].include?(ActiveScaffold.js_framework)
|
7
|
+
end
|
8
|
+
def self.stylesheets
|
9
|
+
'chosen'
|
10
|
+
end
|
11
|
+
def self.javascripts
|
12
|
+
["chosen-#{ActiveScaffold.js_framework}", "#{ActiveScaffold.js_framework}/active_scaffold_chosen"]
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class ActiveScaffold::Bridges::Chosen
|
2
|
+
module Helpers
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
include FormColumnHelpers
|
6
|
+
include SearchColumnHelpers
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module FormColumnHelpers
|
11
|
+
# requires RecordSelect plugin to be installed and configured.
|
12
|
+
def active_scaffold_input_chosen(column, html_options)
|
13
|
+
html_options[:class] << ' chosen'
|
14
|
+
if column.plural_association?
|
15
|
+
associated_options, select_options = active_scaffold_plural_association_options(column)
|
16
|
+
options = {:selected => associated_options.collect {|a| a[1]}, :include_blank => as_(:_select_)}
|
17
|
+
|
18
|
+
html_options.update(:multiple => true).update(column.options[:html_options] || {})
|
19
|
+
options.update(column.options)
|
20
|
+
html_options[:name] = "#{html_options[:name]}[]" if html_options[:multiple] == true && !html_options[:name].to_s.ends_with?("[]")
|
21
|
+
|
22
|
+
if optgroup = options.delete(:optgroup)
|
23
|
+
select(:record, column.name, grouped_options_for_select(column, select_options, optgroup), options, html_options)
|
24
|
+
else
|
25
|
+
collection_select(:record, column.name, select_options, :id, :to_label, options, html_options)
|
26
|
+
end
|
27
|
+
else
|
28
|
+
active_scaffold_input_select(column, html_options)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module SearchColumnHelpers
|
34
|
+
def active_scaffold_search_chosen(column, options)
|
35
|
+
options[:class] << ' chosen'
|
36
|
+
active_scaffold_search_select(column, options)
|
37
|
+
end
|
38
|
+
|
39
|
+
def active_scaffold_search_multi_chosen(column, options)
|
40
|
+
options[:class] << ' chosen'
|
41
|
+
options[:multiple] = true
|
42
|
+
active_scaffold_search_select(column, options)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
ActionView::Base.class_eval { include ActiveScaffold::Bridges::Chosen::Helpers }
|