active_scaffold 3.0.23 → 3.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/frontends/default/views/_action_group.html.erb +1 -1
- data/frontends/default/views/_action_group.html.erb~ +24 -0
- data/frontends/default/views/_form.html.erb~ +26 -0
- data/frontends/default/views/_form_association.html.erb~ +19 -0
- data/frontends/default/views/_form_association_footer.html.erb~ +16 -6
- data/frontends/default/views/_horizontal_subform.html.erb~ +29 -0
- data/frontends/default/views/_horizontal_subform_header.html.erb~ +3 -2
- data/frontends/default/views/_list_actions.html.erb~ +15 -0
- data/frontends/default/views/_list_inline_adapter.html.erb~ +10 -0
- data/frontends/default/views/_list_messages.html.erb~ +30 -0
- data/frontends/default/views/_list_pagination.html.erb~ +11 -0
- data/frontends/default/views/_list_pagination_links.html.erb~ +0 -0
- data/frontends/default/views/_render_field.js.erb~ +23 -0
- data/frontends/default/views/_row.html.erb~ +6 -0
- data/frontends/default/views/_vertical_subform.html.erb~ +12 -0
- data/frontends/default/views/edit_associated.js.erb~ +13 -0
- data/frontends/default/views/on_create.js.rjs +2 -2
- data/frontends/default/views/render_field.js.erb~ +1 -0
- data/lib/active_scaffold/actions/core.rb~ +13 -5
- data/lib/active_scaffold/actions/create.rb~ +149 -0
- data/lib/active_scaffold/actions/list.rb~ +196 -0
- data/lib/active_scaffold/actions/nested.rb +6 -2
- data/lib/active_scaffold/actions/nested.rb~ +252 -0
- data/lib/active_scaffold/actions/search.rb~ +49 -0
- data/lib/active_scaffold/actions/subform.rb~ +27 -0
- data/lib/active_scaffold/actions/update.rb~ +149 -0
- data/lib/active_scaffold/attribute_params.rb~ +202 -0
- data/lib/active_scaffold/bridges/record_select/{lib/record_select_bridge.rb~ → helpers.rb~} +7 -16
- data/lib/active_scaffold/bridges/shared/date_bridge.rb~ +209 -0
- data/lib/active_scaffold/config/create.rb +4 -4
- data/lib/active_scaffold/config/nested.rb +1 -0
- data/lib/active_scaffold/config/nested.rb~ +41 -0
- data/lib/active_scaffold/config/search.rb~ +74 -0
- data/lib/active_scaffold/constraints.rb~ +186 -0
- data/lib/active_scaffold/data_structures/action_columns.rb~ +140 -0
- data/lib/active_scaffold/data_structures/action_link.rb +4 -4
- data/lib/active_scaffold/data_structures/action_link.rb~ +179 -0
- data/lib/active_scaffold/data_structures/nested_info.rb~ +124 -0
- data/lib/active_scaffold/extensions/action_controller_rendering.rb~ +22 -0
- data/lib/active_scaffold/extensions/action_view_rendering.rb~ +108 -0
- data/lib/active_scaffold/extensions/cache_association.rb~ +12 -0
- data/lib/active_scaffold/extensions/reverse_associations.rb~ +64 -0
- data/lib/active_scaffold/extensions/routing_mapper.rb~ +34 -0
- data/lib/active_scaffold/extensions/unsaved_associated.rb~ +62 -0
- data/lib/active_scaffold/finder.rb~ +370 -0
- data/lib/active_scaffold/helpers/controller_helpers.rb~ +101 -0
- data/lib/active_scaffold/helpers/form_column_helpers.rb~ +321 -0
- data/lib/active_scaffold/helpers/id_helpers.rb~ +123 -0
- data/lib/active_scaffold/helpers/list_column_helpers.rb +9 -6
- data/lib/active_scaffold/helpers/list_column_helpers.rb~ +368 -0
- data/lib/active_scaffold/helpers/search_column_helpers.rb~ +94 -46
- data/lib/active_scaffold/helpers/view_helpers.rb +1 -1
- data/lib/active_scaffold/helpers/view_helpers.rb~ +353 -0
- data/lib/active_scaffold/version.rb +1 -1
- data/lib/active_scaffold.rb +1 -1
- data/lib/active_scaffold.rb~ +362 -0
- metadata +110 -76
- data/lib/active_scaffold/bridges/dragonfly/bridge.rb~ +0 -12
- data/lib/active_scaffold/bridges/dragonfly/lib/dragonfly_bridge.rb~ +0 -36
- data/lib/active_scaffold/bridges/dragonfly/lib/dragonfly_bridge_helpers.rb~ +0 -12
- data/lib/active_scaffold/bridges/dragonfly/lib/form_ui.rb~ +0 -27
- data/lib/active_scaffold/bridges/dragonfly/lib/list_ui.rb~ +0 -16
@@ -0,0 +1,196 @@
|
|
1
|
+
module ActiveScaffold::Actions
|
2
|
+
module List
|
3
|
+
def self.included(base)
|
4
|
+
base.before_filter :list_authorized_filter, :only => [:index, :row]
|
5
|
+
base.helper_method :list_columns
|
6
|
+
end
|
7
|
+
|
8
|
+
def index
|
9
|
+
list
|
10
|
+
end
|
11
|
+
|
12
|
+
# get just a single row
|
13
|
+
def row
|
14
|
+
@record = find_if_allowed(params[:id], :read)
|
15
|
+
respond_to_action(:row)
|
16
|
+
end
|
17
|
+
|
18
|
+
def list
|
19
|
+
do_list
|
20
|
+
do_new if active_scaffold_config.list.always_show_create
|
21
|
+
@record ||= new_model if active_scaffold_config.list.always_show_search
|
22
|
+
@nested_auto_open = active_scaffold_config.list.nested_auto_open
|
23
|
+
respond_to_action(:list)
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
def list_respond_to_html
|
28
|
+
if params.delete(:embedded)
|
29
|
+
render :action => 'list', :layout => false
|
30
|
+
else
|
31
|
+
render :action => 'list'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
def list_respond_to_js
|
35
|
+
if params[:adapter]
|
36
|
+
render(:partial => 'list_with_header')
|
37
|
+
elsif params[:embedded]
|
38
|
+
params.delete(:embedded)
|
39
|
+
render(:partial => 'list_with_header')
|
40
|
+
else
|
41
|
+
render :action => 'list.js'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
def list_respond_to_xml
|
45
|
+
render :xml => response_object.to_xml(:only => list_columns_names), :content_type => Mime::XML, :status => response_status
|
46
|
+
end
|
47
|
+
def list_respond_to_json
|
48
|
+
render :text => response_object.to_json(:only => list_columns_names), :content_type => Mime::JSON, :status => response_status
|
49
|
+
end
|
50
|
+
def list_respond_to_yaml
|
51
|
+
render :text => Hash.from_xml(response_object.to_xml(:only => list_columns_names)).to_yaml, :content_type => Mime::YAML, :status => response_status
|
52
|
+
end
|
53
|
+
|
54
|
+
def row_respond_to_html
|
55
|
+
render(:partial => 'row', :locals => {:record => @record})
|
56
|
+
end
|
57
|
+
|
58
|
+
# The actual algorithm to prepare for the list view
|
59
|
+
def set_includes_for_list_columns
|
60
|
+
includes_for_list_columns = active_scaffold_config.list.columns.collect{ |c| c.includes }.flatten.uniq.compact
|
61
|
+
self.active_scaffold_includes.concat includes_for_list_columns
|
62
|
+
end
|
63
|
+
|
64
|
+
# The actual algorithm to prepare for the list view
|
65
|
+
def do_list
|
66
|
+
set_includes_for_list_columns
|
67
|
+
|
68
|
+
options = { :sorting => active_scaffold_config.list.user.sorting,
|
69
|
+
:count_includes => active_scaffold_config.list.user.count_includes }
|
70
|
+
paginate = (params[:format].nil?) ? (accepts? :html, :js) : ['html', 'js'].include?(params[:format])
|
71
|
+
if paginate
|
72
|
+
options.merge!({
|
73
|
+
:per_page => active_scaffold_config.list.user.per_page,
|
74
|
+
:page => active_scaffold_config.list.user.page,
|
75
|
+
:pagination => active_scaffold_config.list.pagination
|
76
|
+
})
|
77
|
+
end
|
78
|
+
|
79
|
+
page = find_page(options)
|
80
|
+
if page.items.blank? && !page.pager.infinite?
|
81
|
+
page = page.pager.last
|
82
|
+
active_scaffold_config.list.user.page = page.number
|
83
|
+
end
|
84
|
+
@page, @records = page, page.items
|
85
|
+
end
|
86
|
+
|
87
|
+
def each_record_in_page
|
88
|
+
_page = active_scaffold_config.list.user.page
|
89
|
+
do_search if respond_to? :do_search
|
90
|
+
active_scaffold_config.list.user.page = _page
|
91
|
+
do_list
|
92
|
+
@page.items.each {|record| yield record}
|
93
|
+
end
|
94
|
+
|
95
|
+
def each_record_in_scope
|
96
|
+
do_search if respond_to? :do_search
|
97
|
+
finder_options = { :order => "#{active_scaffold_config.model.connection.quote_table_name(active_scaffold_config.model.table_name)}.#{active_scaffold_config.model.primary_key} ASC",
|
98
|
+
:conditions => all_conditions,
|
99
|
+
:joins => joins_for_finder}
|
100
|
+
finder_options.merge! custom_finder_options
|
101
|
+
finder_options.merge! :include => (active_scaffold_includes.blank? ? nil : active_scaffold_includes)
|
102
|
+
klass = beginning_of_chain
|
103
|
+
klass.all(finder_options).each {|record| yield record}
|
104
|
+
end
|
105
|
+
|
106
|
+
# The default security delegates to ActiveRecordPermissions.
|
107
|
+
# You may override the method to customize.
|
108
|
+
def list_authorized?
|
109
|
+
authorized_for?(:crud_type => :read)
|
110
|
+
end
|
111
|
+
|
112
|
+
# call this method in your action_link action to simplify processing of actions
|
113
|
+
# eg for member action_link :fire
|
114
|
+
# process_action_link_action do |record|
|
115
|
+
# record.update_attributes(:fired => true)
|
116
|
+
# self.successful = true
|
117
|
+
# flash[:info] = 'Player fired'
|
118
|
+
# end
|
119
|
+
def process_action_link_action(render_action = :action_update, crud_type = nil)
|
120
|
+
if request.get?
|
121
|
+
# someone has disabled javascript, we have to show confirmation form first
|
122
|
+
@record = find_if_allowed(params[:id], :read) if params[:id] && params[:id] && params[:id].to_i > 0
|
123
|
+
respond_to_action(:action_confirmation)
|
124
|
+
else
|
125
|
+
if params[:id] && params[:id] && params[:id].to_i > 0
|
126
|
+
crud_type ||= (request.post? || request.put?) ? :update : :delete
|
127
|
+
@record = find_if_allowed(params[:id], crud_type)
|
128
|
+
unless @record.nil?
|
129
|
+
yield @record
|
130
|
+
else
|
131
|
+
self.successful = false
|
132
|
+
flash[:error] = as_(:no_authorization_for_action, :action => action_name)
|
133
|
+
end
|
134
|
+
else
|
135
|
+
yield
|
136
|
+
end
|
137
|
+
respond_to_action(render_action)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def action_confirmation_respond_to_html(confirm_action = action_name.to_sym)
|
142
|
+
link = active_scaffold_config.action_links[confirm_action]
|
143
|
+
render :action => 'action_confirmation', :locals => {:record => @record, :link => link}
|
144
|
+
end
|
145
|
+
|
146
|
+
def action_update_respond_to_html
|
147
|
+
do_search if respond_to? :do_search
|
148
|
+
do_list
|
149
|
+
redirect_to :action => 'index'
|
150
|
+
end
|
151
|
+
|
152
|
+
def action_update_respond_to_js
|
153
|
+
render(:action => 'on_action_update')
|
154
|
+
end
|
155
|
+
|
156
|
+
def action_update_respond_to_xml
|
157
|
+
render :xml => successful? ? "" : response_object.to_xml(:only => list_columns_names), :content_type => Mime::XML, :status => response_status
|
158
|
+
end
|
159
|
+
|
160
|
+
def action_update_respond_to_json
|
161
|
+
render :text => successful? ? "" : response_object.to_json(:only => list_columns_names), :content_type => Mime::JSON, :status => response_status
|
162
|
+
end
|
163
|
+
|
164
|
+
def action_update_respond_to_yaml
|
165
|
+
render :text => successful? ? "" : Hash.from_xml(response_object.to_xml(:only => list_columns_names)).to_yaml, :content_type => Mime::YAML, :status => response_status
|
166
|
+
end
|
167
|
+
|
168
|
+
private
|
169
|
+
def list_authorized_filter
|
170
|
+
raise ActiveScaffold::ActionNotAllowed unless list_authorized?
|
171
|
+
end
|
172
|
+
|
173
|
+
def list_formats
|
174
|
+
(default_formats + active_scaffold_config.formats + active_scaffold_config.list.formats).uniq
|
175
|
+
end
|
176
|
+
alias_method :index_formats, :list_formats
|
177
|
+
|
178
|
+
alias_method :row_formats, :list_formats
|
179
|
+
|
180
|
+
def action_update_formats
|
181
|
+
(default_formats + active_scaffold_config.formats).uniq
|
182
|
+
end
|
183
|
+
|
184
|
+
def action_confirmation_formats
|
185
|
+
(default_formats + active_scaffold_config.formats).uniq
|
186
|
+
end
|
187
|
+
|
188
|
+
def list_columns
|
189
|
+
active_scaffold_config.list.columns.collect_visible
|
190
|
+
end
|
191
|
+
|
192
|
+
def list_columns_names
|
193
|
+
list_columns.collect(&:name)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
@@ -82,8 +82,12 @@ module ActiveScaffold::Actions
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def beginning_of_chain
|
85
|
-
if nested? && nested.association && nested.association.
|
86
|
-
nested.
|
85
|
+
if nested? && nested.association && !nested.association.belongs_to?
|
86
|
+
if nested.association.collection?
|
87
|
+
nested.parent_scope.send(nested.association.name)
|
88
|
+
elsif nested.child_association.belongs_to?
|
89
|
+
active_scaffold_config.model.where(nested.child_association.foreign_key => nested.parent_scope)
|
90
|
+
end
|
87
91
|
elsif nested? && nested.scope
|
88
92
|
nested.parent_scope.send(nested.scope)
|
89
93
|
else
|
@@ -0,0 +1,252 @@
|
|
1
|
+
module ActiveScaffold::Actions
|
2
|
+
# The Nested module basically handles automatically linking controllers together. It does this by creating column links with the right parameters, and by providing any supporting systems (like a /:controller/nested action for returning associated scaffolds).
|
3
|
+
module Nested
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
super
|
7
|
+
base.module_eval do
|
8
|
+
before_filter :register_constraints_with_action_columns
|
9
|
+
before_filter :set_nested
|
10
|
+
before_filter :configure_nested
|
11
|
+
include ActiveScaffold::Actions::Nested::ChildMethods if active_scaffold_config.model.reflect_on_all_associations.any? {|a| a.macro == :has_and_belongs_to_many}
|
12
|
+
end
|
13
|
+
base.before_filter :include_habtm_actions
|
14
|
+
base.helper_method :nested
|
15
|
+
base.helper_method :nested_parent_record
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
def nested
|
20
|
+
@nested ||= ActiveScaffold::DataStructures::NestedInfo.get(active_scaffold_config.model, active_scaffold_session_storage)
|
21
|
+
if !@nested.nil? && @nested.new_instance?
|
22
|
+
register_constraints_with_action_columns(@nested.constrained_fields, active_scaffold_config.list.hide_nested_column ? [] : [:list])
|
23
|
+
active_scaffold_constraints[:id] = params[:id] if @nested.belongs_to?
|
24
|
+
end
|
25
|
+
@nested
|
26
|
+
end
|
27
|
+
|
28
|
+
def nested?
|
29
|
+
!nested.nil?
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_nested
|
33
|
+
if params[:parent_scaffold] && ((params[:association] && params[:assoc_id]) || params[:named_scope])
|
34
|
+
@nested = nil
|
35
|
+
active_scaffold_session_storage[:nested] = {:parent_scaffold => params[:parent_scaffold].to_s,
|
36
|
+
:name => (params[:association] || params[:named_scope]).to_sym,
|
37
|
+
:parent_id => params[:assoc_id]}
|
38
|
+
params.delete_if {|key, value| [:parent_scaffold, :association, :named_scope, :assoc_id].include? key.to_sym}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def configure_nested
|
43
|
+
if nested?
|
44
|
+
active_scaffold_session_storage[:list][:label] = if nested.belongs_to?
|
45
|
+
as_(:nested_of_model, :nested_model => active_scaffold_config.model.model_name.human, :parent_model => nested_parent_record.to_label)
|
46
|
+
else
|
47
|
+
as_(:nested_for_model, :nested_model => active_scaffold_config.list.label, :parent_model => nested_parent_record.to_label)
|
48
|
+
end
|
49
|
+
if nested.sorted?
|
50
|
+
active_scaffold_config.list.user.nested_default_sorting = {:table_name => active_scaffold_config.model.model_name, :default_sorting => nested.default_sorting}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def nested_authorized?(record = nil)
|
56
|
+
true
|
57
|
+
end
|
58
|
+
|
59
|
+
def include_habtm_actions
|
60
|
+
if nested?
|
61
|
+
if nested.habtm?
|
62
|
+
# Production mode is ok with adding a link everytime the scaffold is nested - we ar not ok with that.
|
63
|
+
active_scaffold_config.action_links.add('new_existing', :label => :add_existing, :type => :collection, :security_method => :add_existing_authorized?) unless active_scaffold_config.action_links['new_existing']
|
64
|
+
if active_scaffold_config.nested.shallow_delete
|
65
|
+
active_scaffold_config.action_links.add('destroy_existing', :label => :remove, :type => :member, :confirm => :are_you_sure_to_delete, :method => :delete, :position => false, :security_method => :delete_existing_authorized?) unless active_scaffold_config.action_links['destroy_existing']
|
66
|
+
if active_scaffold_config.actions.include?(:delete)
|
67
|
+
active_scaffold_config.action_links.delete("delete") if active_scaffold_config.action_links['delete']
|
68
|
+
end
|
69
|
+
end
|
70
|
+
else
|
71
|
+
# Production mode is caching this link into a non nested scaffold
|
72
|
+
active_scaffold_config.action_links.delete('new_existing') if active_scaffold_config.action_links['new_existing']
|
73
|
+
|
74
|
+
if active_scaffold_config.nested.shallow_delete
|
75
|
+
active_scaffold_config.action_links.delete("destroy_existing") if active_scaffold_config.action_links['destroy_existing']
|
76
|
+
if active_scaffold_config.actions.include?(:delete)
|
77
|
+
active_scaffold_config.action_links.add(ActiveScaffold::Config::Delete.link) unless active_scaffold_config.action_links['delete']
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def beginning_of_chain
|
85
|
+
if nested? && nested.association && !nested.association.belongs_to?
|
86
|
+
debugger
|
87
|
+
if nested.association.collection?
|
88
|
+
nested.parent_scope.send(nested.association.name)
|
89
|
+
elsif nested.child_association.belongs_to?
|
90
|
+
active_scaffold_config.model.where(nested.child_association.foreign_key => nested.parent_scope)
|
91
|
+
end
|
92
|
+
elsif nested? && nested.scope
|
93
|
+
nested.parent_scope.send(nested.scope)
|
94
|
+
else
|
95
|
+
active_scaffold_config.model
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def nested_parent_record(crud = :read)
|
100
|
+
@nested_parent_record ||= find_if_allowed(nested.parent_id, crud, nested.parent_model)
|
101
|
+
end
|
102
|
+
|
103
|
+
def create_association_with_parent(record)
|
104
|
+
if nested?
|
105
|
+
if (nested.belongs_to? || nested.has_one? || nested.habtm?) && nested.child_association
|
106
|
+
parent = nested_parent_record(:read)
|
107
|
+
case nested.child_association.macro
|
108
|
+
when :has_one
|
109
|
+
record.send("#{nested.child_association.name}=", parent)
|
110
|
+
when :belongs_to
|
111
|
+
record.send("#{nested.child_association.name}=", parent)
|
112
|
+
when :has_many, :has_and_belongs_to_many
|
113
|
+
record.send("#{nested.child_association.name}").send(:<<, parent)
|
114
|
+
end unless parent.nil?
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
def nested_formats
|
121
|
+
(default_formats + active_scaffold_config.formats + active_scaffold_config.nested.formats).uniq
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
module ActiveScaffold::Actions::Nested
|
127
|
+
module ChildMethods
|
128
|
+
|
129
|
+
def self.included(base)
|
130
|
+
super
|
131
|
+
end
|
132
|
+
|
133
|
+
def new_existing
|
134
|
+
do_new
|
135
|
+
respond_to_action(:new_existing)
|
136
|
+
end
|
137
|
+
|
138
|
+
def add_existing
|
139
|
+
do_add_existing
|
140
|
+
respond_to_action(:add_existing)
|
141
|
+
end
|
142
|
+
|
143
|
+
def destroy_existing
|
144
|
+
return redirect_to(params.merge(:action => :delete)) if request.get?
|
145
|
+
do_destroy_existing
|
146
|
+
respond_to_action(:destroy_existing)
|
147
|
+
end
|
148
|
+
|
149
|
+
protected
|
150
|
+
def new_existing_respond_to_html
|
151
|
+
if successful?
|
152
|
+
render(:action => 'add_existing_form')
|
153
|
+
else
|
154
|
+
return_to_main
|
155
|
+
end
|
156
|
+
end
|
157
|
+
def new_existing_respond_to_js
|
158
|
+
render(:partial => 'add_existing_form')
|
159
|
+
end
|
160
|
+
def add_existing_respond_to_html
|
161
|
+
if successful?
|
162
|
+
flash[:info] = as_(:created_model, :model => @record.to_label)
|
163
|
+
return_to_main
|
164
|
+
else
|
165
|
+
render(:action => 'add_existing_form')
|
166
|
+
end
|
167
|
+
end
|
168
|
+
def add_existing_respond_to_js
|
169
|
+
if successful?
|
170
|
+
render :action => 'add_existing'
|
171
|
+
else
|
172
|
+
render :action => 'form_messages'
|
173
|
+
end
|
174
|
+
end
|
175
|
+
def add_existing_respond_to_xml
|
176
|
+
render :xml => response_object.to_xml(:only => active_scaffold_config.list.columns.names), :content_type => Mime::XML, :status => response_status
|
177
|
+
end
|
178
|
+
def add_existing_respond_to_json
|
179
|
+
render :text => response_object.to_json(:only => active_scaffold_config.list.columns.names), :content_type => Mime::JSON, :status => response_status
|
180
|
+
end
|
181
|
+
def add_existing_respond_to_yaml
|
182
|
+
render :text => Hash.from_xml(response_object.to_xml(:only => active_scaffold_config.list.columns.names)).to_yaml, :content_type => Mime::YAML, :status => response_status
|
183
|
+
end
|
184
|
+
def destroy_existing_respond_to_html
|
185
|
+
flash[:info] = as_(:deleted_model, :model => @record.to_label)
|
186
|
+
return_to_main
|
187
|
+
end
|
188
|
+
|
189
|
+
def destroy_existing_respond_to_js
|
190
|
+
render(:action => 'destroy')
|
191
|
+
end
|
192
|
+
|
193
|
+
def destroy_existing_respond_to_xml
|
194
|
+
render :xml => successful? ? "" : response_object.to_xml(:only => active_scaffold_config.list.columns.names), :content_type => Mime::XML, :status => response_status
|
195
|
+
end
|
196
|
+
|
197
|
+
def destroy_existing_respond_to_json
|
198
|
+
render :text => successful? ? "" : response_object.to_json(:only => active_scaffold_config.list.columns.names), :content_type => Mime::JSON, :status => response_status
|
199
|
+
end
|
200
|
+
|
201
|
+
def destroy_existing_respond_to_yaml
|
202
|
+
render :text => successful? ? "" : Hash.from_xml(response_object.to_xml(:only => active_scaffold_config.list.columns.names)).to_yaml, :content_type => Mime::YAML, :status => response_status
|
203
|
+
end
|
204
|
+
|
205
|
+
def add_existing_authorized?(record = nil)
|
206
|
+
true
|
207
|
+
end
|
208
|
+
def delete_existing_authorized?(record = nil)
|
209
|
+
true
|
210
|
+
end
|
211
|
+
|
212
|
+
def after_create_save(record)
|
213
|
+
if params[:association_macro] == :has_and_belongs_to_many
|
214
|
+
params[:associated_id] = record
|
215
|
+
do_add_existing
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
# The actual "add_existing" algorithm
|
220
|
+
def do_add_existing
|
221
|
+
parent_record = nested_parent_record(:update)
|
222
|
+
@record = active_scaffold_config.model.find(params[:associated_id])
|
223
|
+
if parent_record && @record
|
224
|
+
parent_record.send(nested.association.name) << @record
|
225
|
+
parent_record.save
|
226
|
+
else
|
227
|
+
false
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def do_destroy_existing
|
232
|
+
if active_scaffold_config.nested.shallow_delete
|
233
|
+
@record = nested_parent_record(:update)
|
234
|
+
collection = @record.send(nested.association.name)
|
235
|
+
assoc_record = collection.find(params[:id])
|
236
|
+
collection.delete(assoc_record)
|
237
|
+
else
|
238
|
+
do_destroy
|
239
|
+
end
|
240
|
+
end
|
241
|
+
private
|
242
|
+
def new_existing_formats
|
243
|
+
(default_formats + active_scaffold_config.formats).uniq
|
244
|
+
end
|
245
|
+
def add_existing_formats
|
246
|
+
(default_formats + active_scaffold_config.formats).uniq
|
247
|
+
end
|
248
|
+
def destroy_existing_formats
|
249
|
+
(default_formats + active_scaffold_config.formats).uniq
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module ActiveScaffold::Actions
|
2
|
+
module Search
|
3
|
+
include ActiveScaffold::Actions::CommonSearch
|
4
|
+
def self.included(base)
|
5
|
+
base.before_filter :search_authorized_filter, :only => :show_search
|
6
|
+
base.before_filter :store_search_params_into_session, :only => [:index]
|
7
|
+
base.before_filter :do_search, :only => [:index]
|
8
|
+
base.helper_method :search_params
|
9
|
+
end
|
10
|
+
|
11
|
+
def show_search
|
12
|
+
respond_to_action(:search)
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
def search_respond_to_html
|
17
|
+
render(:action => "search")
|
18
|
+
end
|
19
|
+
def search_respond_to_js
|
20
|
+
render(:partial => "search")
|
21
|
+
end
|
22
|
+
def do_search
|
23
|
+
query = search_params.to_s.strip rescue ''
|
24
|
+
unless query.empty?
|
25
|
+
columns = active_scaffold_config.search.columns
|
26
|
+
text_search = active_scaffold_config.search.text_search
|
27
|
+
query = query.split(active_scaffold_config.search.split_terms) if active_scaffold_config.search.split_terms
|
28
|
+
debugger
|
29
|
+
search_conditions = self.class.create_conditions_for_columns(query, columns, text_search)
|
30
|
+
self.active_scaffold_conditions = merge_conditions(self.active_scaffold_conditions, search_conditions)
|
31
|
+
@filtered = !search_conditions.blank?
|
32
|
+
|
33
|
+
includes_for_search_columns = columns.collect{ |column| column.includes}.flatten.uniq.compact
|
34
|
+
self.active_scaffold_includes.concat includes_for_search_columns
|
35
|
+
|
36
|
+
active_scaffold_config.list.user.page = nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
def search_authorized_filter
|
42
|
+
link = active_scaffold_config.search.link || active_scaffold_config.search.class.link
|
43
|
+
raise ActiveScaffold::ActionNotAllowed unless self.send(link.security_method)
|
44
|
+
end
|
45
|
+
def search_formats
|
46
|
+
(default_formats + active_scaffold_config.formats + active_scaffold_config.search.formats).uniq
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module ActiveScaffold::Actions
|
2
|
+
module Subform
|
3
|
+
def edit_associated
|
4
|
+
do_edit_associated
|
5
|
+
render :action => 'edit_associated.js'
|
6
|
+
end
|
7
|
+
|
8
|
+
protected
|
9
|
+
|
10
|
+
def do_edit_associated
|
11
|
+
@parent_record = params[:id].nil? ? new_model : find_if_allowed(params[:id], :update)
|
12
|
+
@column = active_scaffold_config.columns[params[:association]]
|
13
|
+
|
14
|
+
# NOTE: we don't check whether the user is allowed to update this record, because if not, we'll still let them associate the record. we'll just refuse to do more than associate, is all.
|
15
|
+
@record = @column.association.klass.find(params[:associated_id]) if params[:associated_id]
|
16
|
+
@record ||= if column.singular_association?
|
17
|
+
parent_record.send("build_#{column.name}".to_sym)
|
18
|
+
else
|
19
|
+
parent_record.send(column.name).buildbuild_associated(column, parent_record)
|
20
|
+
end
|
21
|
+
|
22
|
+
@scope = "[#{@column.name}]"
|
23
|
+
@scope += (@record.new_record?) ? "[#{(Time.now.to_f*1000).to_i.to_s}]" : "[#{@record.id}]" if @column.plural_association?
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
module ActiveScaffold::Actions
|
2
|
+
module Update
|
3
|
+
def self.included(base)
|
4
|
+
base.before_filter :update_authorized_filter, :only => [:edit, :update]
|
5
|
+
base.helper_method :update_refresh_list?
|
6
|
+
end
|
7
|
+
|
8
|
+
def edit
|
9
|
+
do_edit
|
10
|
+
respond_to_action(:edit)
|
11
|
+
end
|
12
|
+
|
13
|
+
def update
|
14
|
+
do_update
|
15
|
+
respond_to_action(:update)
|
16
|
+
end
|
17
|
+
|
18
|
+
# for inline (inlist) editing
|
19
|
+
def update_column
|
20
|
+
do_update_column
|
21
|
+
render :action => 'update_column', :locals => {:column_span_id => params[:editor_id] || params[:editorId]}
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
def edit_respond_to_html
|
26
|
+
if successful?
|
27
|
+
render(:action => 'update')
|
28
|
+
else
|
29
|
+
return_to_main
|
30
|
+
end
|
31
|
+
end
|
32
|
+
def edit_respond_to_js
|
33
|
+
render(:partial => 'update_form')
|
34
|
+
end
|
35
|
+
def update_respond_to_html
|
36
|
+
if params[:iframe]=='true' # was this an iframe post ?
|
37
|
+
responds_to_parent do
|
38
|
+
render :action => 'on_update.js', :layout => false
|
39
|
+
end
|
40
|
+
else # just a regular post
|
41
|
+
if successful?
|
42
|
+
flash[:info] = as_(:updated_model, :model => @record.to_label)
|
43
|
+
return_to_main
|
44
|
+
else
|
45
|
+
render(:action => 'update')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
def update_respond_to_js
|
50
|
+
if successful? && update_refresh_list? && !render_parent?
|
51
|
+
do_search if respond_to? :do_search
|
52
|
+
do_list
|
53
|
+
end
|
54
|
+
render :action => 'on_update'
|
55
|
+
end
|
56
|
+
def update_respond_to_xml
|
57
|
+
render :xml => response_object.to_xml(:only => active_scaffold_config.update.columns.names), :content_type => Mime::XML, :status => response_status
|
58
|
+
end
|
59
|
+
def update_respond_to_json
|
60
|
+
render :text => response_object.to_json(:only => active_scaffold_config.update.columns.names), :content_type => Mime::JSON, :status => response_status
|
61
|
+
end
|
62
|
+
def update_respond_to_yaml
|
63
|
+
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
|
+
end
|
65
|
+
# A simple method to find and prepare a record for editing
|
66
|
+
# May be overridden to customize the record (set default values, etc.)
|
67
|
+
def do_edit
|
68
|
+
register_constraints_with_action_columns(nested.constrained_fields, active_scaffold_config.update.hide_nested_column ? [] : [:update]) if nested?
|
69
|
+
@record = find_if_allowed(params[:id], :update)
|
70
|
+
end
|
71
|
+
|
72
|
+
# A complex method to update a record. The complexity comes from the support for subforms, and saving associated records.
|
73
|
+
# If you want to customize this algorithm, consider using the +before_update_save+ callback
|
74
|
+
def do_update
|
75
|
+
do_edit
|
76
|
+
update_save
|
77
|
+
end
|
78
|
+
|
79
|
+
def update_save(options = {})
|
80
|
+
begin
|
81
|
+
active_scaffold_config.model.transaction do
|
82
|
+
@record = update_record_from_params(@record, active_scaffold_config.update.columns, params[:record]) unless options[:no_record_param_update]
|
83
|
+
before_update_save(@record)
|
84
|
+
self.successful = [@record.valid?, @record.associated_valid?].all? {|v| v == true} # this syntax avoids a short-circuit
|
85
|
+
debugger
|
86
|
+
if successful?
|
87
|
+
@record.save! and @record.save_associated!
|
88
|
+
after_update_save(@record)
|
89
|
+
else
|
90
|
+
# some associations such as habtm are saved before saved is called on parent object
|
91
|
+
# we have to revert these changes if validation fails
|
92
|
+
raise ActiveRecord::Rollback, "don't save habtm associations unless record is valid"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
rescue ActiveRecord::RecordInvalid
|
96
|
+
rescue ActiveRecord::StaleObjectError
|
97
|
+
@record.errors.add(:base, as_(:version_inconsistency))
|
98
|
+
self.successful=false
|
99
|
+
rescue ActiveRecord::RecordNotSaved
|
100
|
+
@record.errors.add(:base, as_(:record_not_saved)) if @record.errors.empty?
|
101
|
+
self.successful = false
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def do_update_column
|
106
|
+
@record = active_scaffold_config.model.find(params[:id])
|
107
|
+
if @record.authorized_for?(:crud_type => :update, :column => params[:column])
|
108
|
+
column = active_scaffold_config.columns[params[:column].to_sym]
|
109
|
+
params[:value] ||= @record.column_for_attribute(params[:column]).default unless @record.column_for_attribute(params[:column]).nil? || @record.column_for_attribute(params[:column]).null
|
110
|
+
unless column.nil?
|
111
|
+
params[:value] = column_value_from_param_value(@record, column, params[:value])
|
112
|
+
params[:value] = [] if params[:value].nil? && column.form_ui && column.plural_association?
|
113
|
+
end
|
114
|
+
@record.send("#{params[:column]}=", params[:value])
|
115
|
+
before_update_save(@record)
|
116
|
+
@record.save
|
117
|
+
after_update_save(@record)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# override this method if you want to inject data in the record (or its associated objects) before the save
|
122
|
+
def before_update_save(record); end
|
123
|
+
|
124
|
+
# override this method if you want to do something after the save
|
125
|
+
def after_update_save(record); end
|
126
|
+
|
127
|
+
# should we refresh whole list after update operation
|
128
|
+
def update_refresh_list?
|
129
|
+
active_scaffold_config.update.refresh_list
|
130
|
+
end
|
131
|
+
|
132
|
+
# The default security delegates to ActiveRecordPermissions.
|
133
|
+
# You may override the method to customize.
|
134
|
+
def update_authorized?(record = nil)
|
135
|
+
(!nested? || !nested.readonly?) && authorized_for?(:crud_type => :update)
|
136
|
+
end
|
137
|
+
private
|
138
|
+
def update_authorized_filter
|
139
|
+
link = active_scaffold_config.update.link || active_scaffold_config.update.class.link
|
140
|
+
raise ActiveScaffold::ActionNotAllowed unless self.send(link.security_method)
|
141
|
+
end
|
142
|
+
def edit_formats
|
143
|
+
(default_formats + active_scaffold_config.formats).uniq
|
144
|
+
end
|
145
|
+
def update_formats
|
146
|
+
(default_formats + active_scaffold_config.formats + active_scaffold_config.update.formats).uniq
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|