active_scaffold 3.3.3 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +39 -0
- data/README.md +5 -3
- data/app/assets/images/active_scaffold/refresh.png +0 -0
- data/app/assets/javascripts/jquery/active_scaffold.js +182 -91
- data/app/assets/javascripts/jquery/date_picker_bridge.js.erb +14 -16
- data/app/assets/javascripts/jquery/draggable_lists.js +33 -26
- data/app/assets/javascripts/jquery/jquery.editinplace.js +3 -3
- data/app/assets/javascripts/prototype/active_scaffold.js +61 -19
- data/app/assets/stylesheets/active_scaffold_colors.css.scss +4 -0
- data/app/assets/stylesheets/active_scaffold_images.css.scss +3 -0
- data/app/assets/stylesheets/active_scaffold_layout.css +23 -2
- data/app/views/active_scaffold_overrides/_add_existing_form.html.erb +1 -3
- data/app/views/active_scaffold_overrides/_base_form.html.erb +7 -5
- data/app/views/active_scaffold_overrides/_field_search.html.erb +1 -2
- data/app/views/active_scaffold_overrides/_form.html.erb +6 -4
- data/app/views/active_scaffold_overrides/_form_association.html.erb +4 -3
- data/app/views/active_scaffold_overrides/_form_association_footer.html.erb +5 -5
- data/app/views/active_scaffold_overrides/_form_association_record.html.erb +8 -6
- data/app/views/active_scaffold_overrides/_horizontal_subform_header.html.erb +3 -2
- data/app/views/active_scaffold_overrides/_list.html.erb +8 -6
- data/app/views/active_scaffold_overrides/_list_column_headings.html.erb +1 -4
- data/app/views/active_scaffold_overrides/_list_pagination.html.erb +4 -4
- data/app/views/active_scaffold_overrides/_list_pagination_links.html.erb +1 -1
- data/app/views/active_scaffold_overrides/_list_record.html.erb +3 -3
- data/app/views/active_scaffold_overrides/_refresh_list.js.erb +8 -1
- data/app/views/active_scaffold_overrides/_search.html.erb +7 -13
- data/app/views/active_scaffold_overrides/_show_columns.html.erb +1 -1
- data/app/views/active_scaffold_overrides/on_create.js.erb +4 -4
- data/app/views/active_scaffold_overrides/render_field_inplace.html.erb +1 -1
- data/app/views/active_scaffold_overrides/row.js.erb +1 -1
- data/config/locales/de.yml +106 -95
- data/config/locales/en.yml +108 -97
- data/config/locales/es.yml +109 -98
- data/config/locales/fr.yml +108 -97
- data/config/locales/hu.yml +109 -98
- data/config/locales/ja.yml +100 -89
- data/config/locales/ru.yml +115 -104
- data/lib/active_scaffold.rb +18 -294
- data/lib/active_scaffold/actions/common_search.rb +50 -17
- data/lib/active_scaffold/actions/core.rb +93 -22
- data/lib/active_scaffold/actions/create.rb +15 -6
- data/lib/active_scaffold/actions/field_search.rb +68 -60
- data/lib/active_scaffold/actions/list.rb +49 -28
- data/lib/active_scaffold/actions/nested.rb +14 -6
- data/lib/active_scaffold/actions/search.rb +36 -35
- data/lib/active_scaffold/actions/show.rb +9 -4
- data/lib/active_scaffold/actions/subform.rb +1 -1
- data/lib/active_scaffold/actions/update.rb +22 -7
- data/lib/active_scaffold/active_record_permissions.rb +125 -118
- data/lib/active_scaffold/attribute_params.rb +84 -66
- data/lib/active_scaffold/bridges.rb +3 -3
- data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +10 -5
- data/lib/active_scaffold/bridges/cancan.rb +2 -1
- data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +13 -2
- data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +11 -6
- data/lib/active_scaffold/bridges/chosen/helpers.rb +2 -2
- data/lib/active_scaffold/bridges/country_helper/country_helper_bridge.rb +45 -29
- data/lib/active_scaffold/bridges/date_picker/ext.rb +11 -6
- data/lib/active_scaffold/bridges/date_picker/helper.rb +5 -1
- data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +10 -5
- data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +6 -1
- data/lib/active_scaffold/bridges/file_column/form_ui.rb +12 -11
- data/lib/active_scaffold/bridges/paperclip/form_ui.rb +14 -6
- data/lib/active_scaffold/bridges/paperclip/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/record_select/helpers.rb +15 -12
- data/lib/active_scaffold/bridges/shared/date_bridge.rb +7 -8
- data/lib/active_scaffold/bridges/tiny_mce.rb +5 -3
- data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +4 -5
- data/lib/active_scaffold/config/base.rb +4 -0
- data/lib/active_scaffold/config/core.rb +12 -5
- data/lib/active_scaffold/config/delete.rb +0 -2
- data/lib/active_scaffold/config/field_search.rb +1 -4
- data/lib/active_scaffold/config/form.rb +0 -2
- data/lib/active_scaffold/config/list.rb +31 -1
- data/lib/active_scaffold/config/search.rb +0 -3
- data/lib/active_scaffold/config/show.rb +0 -6
- data/lib/active_scaffold/config/subform.rb +1 -0
- data/lib/active_scaffold/configurable.rb +2 -2
- data/lib/active_scaffold/constraints.rb +11 -14
- data/lib/active_scaffold/core.rb +277 -0
- data/lib/active_scaffold/data_structures/action_columns.rb +18 -2
- data/lib/active_scaffold/data_structures/action_link.rb +25 -6
- data/lib/active_scaffold/data_structures/action_links.rb +9 -4
- data/lib/active_scaffold/data_structures/actions.rb +1 -1
- data/lib/active_scaffold/data_structures/column.rb +6 -6
- data/lib/active_scaffold/data_structures/columns.rb +2 -2
- data/lib/active_scaffold/data_structures/nested_info.rb +5 -1
- data/lib/active_scaffold/data_structures/sorting.rb +15 -5
- data/lib/active_scaffold/delayed_setup.rb +30 -0
- data/lib/active_scaffold/engine.rb +25 -0
- data/lib/active_scaffold/extensions/action_view_rendering.rb +1 -1
- data/lib/active_scaffold/extensions/left_outer_joins.rb +61 -21
- data/lib/active_scaffold/extensions/localize.rb +1 -1
- data/lib/active_scaffold/extensions/name_option_for_datetime.rb +13 -8
- data/lib/active_scaffold/extensions/paginator_extensions.rb +5 -1
- data/lib/active_scaffold/extensions/reverse_associations.rb +1 -0
- data/lib/active_scaffold/extensions/routing_mapper.rb +1 -1
- data/lib/active_scaffold/extensions/unsaved_record.rb +4 -6
- data/lib/active_scaffold/finder.rb +79 -27
- data/lib/active_scaffold/helpers/association_helpers.rb +48 -18
- data/lib/active_scaffold/helpers/controller_helpers.rb +19 -10
- data/lib/active_scaffold/helpers/form_column_helpers.rb +185 -87
- data/lib/active_scaffold/helpers/human_condition_helpers.rb +2 -1
- data/lib/active_scaffold/helpers/id_helpers.rb +14 -8
- data/lib/active_scaffold/helpers/list_column_helpers.rb +65 -56
- data/lib/active_scaffold/helpers/pagination_helpers.rb +5 -1
- data/lib/active_scaffold/helpers/search_column_helpers.rb +21 -18
- data/lib/active_scaffold/helpers/view_helpers.rb +102 -64
- data/lib/active_scaffold/responds_to_parent.rb +39 -64
- data/lib/active_scaffold/tableless.rb +129 -10
- data/lib/active_scaffold/version.rb +2 -2
- data/test/bridges/bridge_test.rb +1 -1
- data/test/bridges/date_picker_test.rb +2 -2
- data/test/bridges/paperclip_test.rb +10 -8
- data/test/bridges/tiny_mce_test.rb +2 -2
- data/test/company.rb +22 -10
- data/test/config/base_test.rb +1 -1
- data/test/config/core_test.rb +8 -6
- data/test/config/create_test.rb +6 -6
- data/test/config/delete_test.rb +4 -4
- data/test/config/field_search_test.rb +6 -6
- data/test/config/list_test.rb +7 -7
- data/test/config/nested_test.rb +8 -7
- data/test/config/search_test.rb +7 -7
- data/test/config/show_test.rb +5 -5
- data/test/config/subform_test.rb +1 -1
- data/test/config/update_test.rb +5 -4
- data/test/data_structures/action_columns_test.rb +15 -16
- data/test/data_structures/action_link_test.rb +10 -10
- data/test/data_structures/action_links_test.rb +6 -6
- data/test/data_structures/actions_test.rb +4 -4
- data/test/data_structures/association_column_test.rb +4 -4
- data/test/data_structures/column_test.rb +9 -9
- data/test/data_structures/columns_test.rb +7 -7
- data/test/data_structures/error_message_test.rb +2 -4
- data/test/data_structures/set_test.rb +13 -13
- data/test/data_structures/sorting_test.rb +8 -8
- data/test/data_structures/standard_column_test.rb +2 -2
- data/test/data_structures/validation_reflection_test.rb +8 -8
- data/test/data_structures/virtual_column_test.rb +5 -5
- data/test/extensions/active_record_test.rb +1 -1
- data/test/helpers/form_column_helpers_test.rb +5 -5
- data/test/helpers/list_column_helpers_test.rb +2 -1
- data/test/helpers/pagination_helpers_test.rb +1 -1
- data/test/misc/active_record_permissions_test.rb +23 -4
- data/test/misc/attribute_params_test.rb +304 -136
- data/test/misc/calculation_test.rb +55 -0
- data/test/misc/configurable_test.rb +22 -21
- data/test/misc/constraints_test.rb +10 -7
- data/test/misc/convert_numbers_format_test.rb +149 -0
- data/test/misc/finder_test.rb +17 -13
- data/test/misc/lang_test.rb +1 -1
- data/test/misc/tableless_test.rb +18 -0
- data/test/mock_app/app/controllers/addresses_controller.rb +4 -0
- data/test/mock_app/app/controllers/buildings_controller.rb +4 -0
- data/test/mock_app/app/controllers/cars_controller.rb +4 -0
- data/test/mock_app/app/controllers/contacts_controller.rb +4 -0
- data/test/mock_app/app/controllers/floors_controller.rb +6 -0
- data/test/mock_app/app/controllers/people_controller.rb +4 -0
- data/test/mock_app/app/models/address.rb +3 -0
- data/test/mock_app/app/models/building.rb +8 -0
- data/test/mock_app/app/models/car.rb +3 -0
- data/test/mock_app/app/models/contact.rb +3 -0
- data/test/mock_app/app/models/file_model.rb +19 -0
- data/test/mock_app/app/models/floor.rb +8 -0
- data/test/mock_app/app/models/person.rb +11 -0
- data/test/mock_app/config/application.rb +2 -0
- data/test/mock_app/config/environments/test.rb +1 -1
- data/test/mock_app/config/initializers/secret_token.rb +5 -1
- data/test/mock_app/config/routes.rb +1 -1
- data/test/mock_app/db/schema.rb +51 -0
- data/test/model_stub.rb +3 -3
- data/test/test_helper.rb +15 -12
- metadata +51 -50
- data/lib/active_scaffold/extensions/array.rb +0 -7
- data/lib/active_scaffold/extensions/cache_association.rb +0 -16
- data/lib/active_scaffold/extensions/usa_state.rb +0 -46
- data/lib/active_scaffold_env.rb +0 -13
- data/test/extensions/array_test.rb +0 -12
- data/test/mock_app/public/blank.html +0 -33
- data/test/mock_app/public/images/active_scaffold/DO_NOT_EDIT +0 -2
- data/test/mock_app/public/images/active_scaffold/default/add.gif +0 -0
- data/test/mock_app/public/images/active_scaffold/default/arrow_down.gif +0 -0
- data/test/mock_app/public/images/active_scaffold/default/arrow_up.gif +0 -0
- data/test/mock_app/public/images/active_scaffold/default/close.gif +0 -0
- data/test/mock_app/public/images/active_scaffold/default/cross.png +0 -0
- data/test/mock_app/public/images/active_scaffold/default/indicator-small.gif +0 -0
- data/test/mock_app/public/images/active_scaffold/default/indicator.gif +0 -0
- data/test/mock_app/public/images/active_scaffold/default/magnifier.png +0 -0
- data/test/mock_app/public/javascripts/active_scaffold/DO_NOT_EDIT +0 -2
- data/test/mock_app/public/javascripts/active_scaffold/default/active_scaffold.js +0 -532
- data/test/mock_app/public/javascripts/active_scaffold/default/dhtml_history.js +0 -867
- data/test/mock_app/public/javascripts/active_scaffold/default/form_enhancements.js +0 -117
- data/test/mock_app/public/javascripts/active_scaffold/default/rico_corner.js +0 -370
- data/test/mock_app/public/stylesheets/active_scaffold/DO_NOT_EDIT +0 -2
- data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet-ie.css +0 -35
- data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet.css +0 -848
data/lib/active_scaffold.rb
CHANGED
@@ -1,32 +1,16 @@
|
|
1
|
-
unless Rails::VERSION::MAJOR == 3 && Rails::VERSION::MINOR >= 1
|
2
|
-
raise "This version of ActiveScaffold requires Rails 3.1 or higher. Please use an earlier version."
|
3
|
-
end
|
4
|
-
|
5
|
-
begin
|
6
|
-
require 'render_component'
|
7
|
-
rescue LoadError
|
8
|
-
end
|
9
|
-
|
10
|
-
require 'active_scaffold/active_record_permissions'
|
11
|
-
require 'active_scaffold/paginator'
|
12
|
-
require 'active_scaffold/responds_to_parent'
|
13
|
-
|
14
|
-
require 'active_scaffold/version'
|
15
|
-
require 'active_scaffold/engine' unless defined? ACTIVE_SCAFFOLD_PLUGIN
|
16
|
-
require 'json' # for js_config
|
17
|
-
|
18
1
|
module ActiveScaffold
|
2
|
+
autoload :ActiveRecordPermissions, 'active_scaffold/active_record_permissions'
|
19
3
|
autoload :AttributeParams, 'active_scaffold/attribute_params'
|
4
|
+
autoload :Bridges, 'active_scaffold/bridges'
|
20
5
|
autoload :Configurable, 'active_scaffold/configurable'
|
21
6
|
autoload :Constraints, 'active_scaffold/constraints'
|
7
|
+
autoload :Core, 'active_scaffold/core'
|
8
|
+
autoload :DelayedSetup, 'active_scaffold/delayed_setup'
|
22
9
|
autoload :Finder, 'active_scaffold/finder'
|
23
10
|
autoload :MarkedModel, 'active_scaffold/marked_model'
|
24
|
-
autoload :
|
25
|
-
|
26
|
-
|
27
|
-
self.stylesheets = []
|
28
|
-
mattr_accessor :javascripts
|
29
|
-
self.javascripts = []
|
11
|
+
autoload :RespondsToParent, 'active_scaffold/responds_to_parent'
|
12
|
+
autoload :Tableless, 'active_scaffold/tableless'
|
13
|
+
autoload :Version, 'active_scaffold/version'
|
30
14
|
|
31
15
|
def self.autoload_subdir(dir, mod=self, root = File.dirname(__FILE__))
|
32
16
|
Dir["#{root}/active_scaffold/#{dir}/*.rb"].each { |file|
|
@@ -54,82 +38,16 @@ module ActiveScaffold
|
|
54
38
|
end
|
55
39
|
|
56
40
|
class ControllerNotFound < RuntimeError; end
|
57
|
-
class DependencyFailure < RuntimeError; end
|
58
41
|
class MalformedConstraint < RuntimeError; end
|
59
42
|
class RecordNotAllowed < SecurityError; end
|
60
43
|
class ActionNotAllowed < SecurityError; end
|
61
44
|
class ReverseAssociationRequired < RuntimeError; end
|
62
45
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
before_filter :check_input_device
|
69
|
-
end
|
70
|
-
|
71
|
-
base.helper_method :touch_device?
|
72
|
-
base.helper_method :hover_via_click?
|
73
|
-
base.helper_method :active_scaffold_constraints
|
74
|
-
end
|
75
|
-
|
76
|
-
def self.set_defaults(&block)
|
77
|
-
ActiveScaffold::Config::Core.configure &block
|
78
|
-
end
|
79
|
-
|
80
|
-
def active_scaffold_config
|
81
|
-
self.class.active_scaffold_config
|
82
|
-
end
|
83
|
-
|
84
|
-
def active_scaffold_config_for(klass)
|
85
|
-
self.class.active_scaffold_config_for(klass)
|
86
|
-
end
|
87
|
-
|
88
|
-
def active_scaffold_session_storage_key(id = nil)
|
89
|
-
id ||= params[:eid] || "#{params[:controller]}#{"_#{nested.parent_id}" if nested?}"
|
90
|
-
"as:#{id}"
|
91
|
-
end
|
92
|
-
|
93
|
-
def active_scaffold_session_storage(id = nil)
|
94
|
-
session_index = active_scaffold_session_storage_key(id)
|
95
|
-
session[session_index] ||= {}
|
96
|
-
session[session_index]
|
97
|
-
end
|
98
|
-
|
99
|
-
def clear_storage
|
100
|
-
session_index = active_scaffold_session_storage_key
|
101
|
-
session.delete(session_index) unless session[session_index].present?
|
102
|
-
end
|
103
|
-
|
104
|
-
# at some point we need to pass the session and params into config. we'll just take care of that before any particular action occurs by passing those hashes off to the UserSettings class of each action.
|
105
|
-
def handle_user_settings
|
106
|
-
if self.class.uses_active_scaffold?
|
107
|
-
active_scaffold_config.actions.each do |action_name|
|
108
|
-
conf_instance = active_scaffold_config.send(action_name) rescue next
|
109
|
-
next if conf_instance.class::UserSettings == ActiveScaffold::Config::Base::UserSettings # if it hasn't been extended, skip it
|
110
|
-
storage = active_scaffold_config.store_user_settings ? active_scaffold_session_storage : {}
|
111
|
-
conf_instance.user = conf_instance.class::UserSettings.new(conf_instance, storage, params)
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
def check_input_device
|
117
|
-
if request.env["HTTP_USER_AGENT"] && request.env["HTTP_USER_AGENT"][/(iPhone|iPod|iPad)/i]
|
118
|
-
session[:input_device_type] = 'TOUCH'
|
119
|
-
session[:hover_supported] = false
|
120
|
-
else
|
121
|
-
session[:input_device_type] = 'MOUSE'
|
122
|
-
session[:hover_supported] = true
|
123
|
-
end if session[:input_device_type].nil?
|
124
|
-
end
|
125
|
-
|
126
|
-
def touch_device?
|
127
|
-
session[:input_device_type] == 'TOUCH'
|
128
|
-
end
|
129
|
-
|
130
|
-
def hover_via_click?
|
131
|
-
session[:hover_supported] == false
|
132
|
-
end
|
46
|
+
mattr_accessor :delayed_setup
|
47
|
+
mattr_accessor :stylesheets
|
48
|
+
self.stylesheets = []
|
49
|
+
mattr_accessor :javascripts
|
50
|
+
self.javascripts = []
|
133
51
|
|
134
52
|
def self.js_framework=(framework)
|
135
53
|
@@js_framework = framework
|
@@ -151,12 +69,10 @@ module ActiveScaffold
|
|
151
69
|
@@js_config ||= {:scroll_on_close => :checkInViewport}
|
152
70
|
end
|
153
71
|
|
154
|
-
# exclude bridges you do not need
|
72
|
+
# exclude bridges you do not need, add to an initializer
|
155
73
|
# name of bridge subdir should be used to exclude it
|
156
74
|
# eg
|
157
75
|
# ActiveScaffold.exclude_bridges = [:cancan, :ancestry]
|
158
|
-
# if you are using Activescaffold as a gem add to initializer
|
159
|
-
# if you are using Activescaffold as a plugin add to active_scaffold_env.rb
|
160
76
|
def self.exclude_bridges=(bridges)
|
161
77
|
@@exclude_bridges = bridges
|
162
78
|
end
|
@@ -169,203 +85,11 @@ module ActiveScaffold
|
|
169
85
|
File.dirname(__FILE__) + "/.."
|
170
86
|
end
|
171
87
|
|
172
|
-
|
173
|
-
|
174
|
-
extend Prefixes
|
175
|
-
# initialize bridges here
|
176
|
-
ActiveScaffold::Bridges.run_all
|
177
|
-
|
178
|
-
# converts Foo::BarController to 'bar' and FooBarsController to 'foo_bar' and AddressController to 'address'
|
179
|
-
model_id = self.to_s.split('::').last.sub(/Controller$/, '').pluralize.singularize.underscore unless model_id
|
180
|
-
|
181
|
-
# run the configuration
|
182
|
-
@active_scaffold_config = ActiveScaffold::Config::Core.new(model_id)
|
183
|
-
@active_scaffold_config_block = block
|
184
|
-
self.links_for_associations
|
185
|
-
|
186
|
-
self.active_scaffold_superclasses_blocks.each {|superblock| self.active_scaffold_config.configure &superblock}
|
187
|
-
self.active_scaffold_config.sti_children = nil # reset sti_children if set in parent block
|
188
|
-
self.active_scaffold_config.configure &block if block_given?
|
189
|
-
self.active_scaffold_config._configure_sti unless self.active_scaffold_config.sti_children.nil?
|
190
|
-
self.active_scaffold_config._load_action_columns
|
191
|
-
|
192
|
-
# defines the attribute read methods on the model, so record.send() doesn't find protected/private methods instead
|
193
|
-
klass = self.active_scaffold_config.model
|
194
|
-
klass.define_attribute_methods unless klass.attribute_methods_generated?
|
195
|
-
# include the rest of the code into the controller: the action core and the included actions
|
196
|
-
module_eval do
|
197
|
-
include ActiveScaffold::Finder
|
198
|
-
include ActiveScaffold::Constraints
|
199
|
-
include ActiveScaffold::AttributeParams
|
200
|
-
include ActiveScaffold::Actions::Core
|
201
|
-
active_scaffold_config.actions.each do |mod|
|
202
|
-
name = mod.to_s.camelize
|
203
|
-
include "ActiveScaffold::Actions::#{name}".constantize
|
204
|
-
|
205
|
-
# sneak the action links from the actions into the main set
|
206
|
-
if link = active_scaffold_config.send(mod).link rescue nil
|
207
|
-
if link.is_a? Array
|
208
|
-
link.each {|current| active_scaffold_config.action_links.add_to_group(current, active_scaffold_config.send(mod).action_group)}
|
209
|
-
elsif link.is_a? ActiveScaffold::DataStructures::ActionLink
|
210
|
-
active_scaffold_config.action_links.add_to_group(link, active_scaffold_config.send(mod).action_group)
|
211
|
-
end
|
212
|
-
end
|
213
|
-
end
|
214
|
-
end
|
215
|
-
self._add_sti_create_links if self.active_scaffold_config.add_sti_create_links?
|
216
|
-
end
|
217
|
-
|
218
|
-
module Prefixes
|
219
|
-
def parent_prefixes
|
220
|
-
@parent_prefixes ||= super << 'active_scaffold_overrides'
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
# To be called after include action modules
|
225
|
-
def _add_sti_create_links
|
226
|
-
new_action_link = active_scaffold_config.action_links.collection['new']
|
227
|
-
unless new_action_link.nil? || active_scaffold_config.sti_children.empty?
|
228
|
-
active_scaffold_config.action_links.collection.delete('new')
|
229
|
-
active_scaffold_config.sti_children.each do |child|
|
230
|
-
new_sti_link = Marshal.load(Marshal.dump(new_action_link)) # deep clone
|
231
|
-
new_sti_link.label = as_(:create_model, :model => child.to_s.camelize.constantize.model_name.human)
|
232
|
-
new_sti_link.parameters = {:parent_sti => controller_path}
|
233
|
-
new_sti_link.controller = Proc.new { active_scaffold_controller_for(child.to_s.camelize.constantize).controller_path }
|
234
|
-
active_scaffold_config.action_links.collection.create.add(new_sti_link)
|
235
|
-
end
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
# Create the automatic column links. Note that this has to happen when configuration is *done*, because otherwise the Nested module could be disabled. Actually, it could still be disabled later, couldn't it?
|
240
|
-
def links_for_associations
|
241
|
-
return unless active_scaffold_config.actions.include? :list and active_scaffold_config.actions.include? :nested
|
242
|
-
active_scaffold_config.columns.each do |column|
|
243
|
-
next unless column.link.nil? and column.autolink?
|
244
|
-
#lazy load of action_link, cause it was really slowing down app in dev mode
|
245
|
-
#and might lead to trouble cause of cyclic constantization of controllers
|
246
|
-
#and might be unnecessary cause it is done before columns are configured
|
247
|
-
column.set_link(Proc.new {|col| link_for_association(col)})
|
248
|
-
end
|
249
|
-
end
|
250
|
-
|
251
|
-
def active_scaffold_controller_for_column(column, options = {})
|
252
|
-
begin
|
253
|
-
if column.polymorphic_association?
|
254
|
-
:polymorph
|
255
|
-
elsif options.include?(:controller)
|
256
|
-
"#{options[:controller].to_s.camelize}Controller".constantize
|
257
|
-
else
|
258
|
-
active_scaffold_controller_for(column.association.klass)
|
259
|
-
end
|
260
|
-
rescue ActiveScaffold::ControllerNotFound
|
261
|
-
nil
|
262
|
-
end
|
263
|
-
end
|
264
|
-
|
265
|
-
def link_for_association(column, options = {})
|
266
|
-
controller = active_scaffold_controller_for_column(column, options)
|
267
|
-
|
268
|
-
unless controller.nil?
|
269
|
-
options.reverse_merge! :position => :after, :type => :member, :controller => (controller == :polymorph ? controller : controller.controller_path), :column => column
|
270
|
-
options[:parameters] ||= {}
|
271
|
-
options[:parameters].reverse_merge! :association => column.association.name
|
272
|
-
if column.plural_association?
|
273
|
-
# note: we can't create nested scaffolds on :through associations because there's no reverse association.
|
274
|
-
|
275
|
-
ActiveScaffold::DataStructures::ActionLink.new('index', options.merge(:refresh_on_close => true)) #unless column.through_association?
|
276
|
-
else
|
277
|
-
actions = controller.active_scaffold_config.actions unless controller == :polymorph
|
278
|
-
actions ||= [:create, :update, :show]
|
279
|
-
column.actions_for_association_links.delete :new unless actions.include? :create
|
280
|
-
column.actions_for_association_links.delete :edit unless actions.include? :update
|
281
|
-
column.actions_for_association_links.delete :show unless actions.include? :show
|
282
|
-
ActiveScaffold::DataStructures::ActionLink.new(nil, options.merge(:html_options => {:class => column.name}))
|
283
|
-
end
|
284
|
-
end
|
285
|
-
end
|
286
|
-
|
287
|
-
def link_for_association_as_scope(scope, options = {})
|
288
|
-
options.reverse_merge! :label => scope, :position => :after, :type => :member, :controller => controller_path
|
289
|
-
options[:parameters] ||= {}
|
290
|
-
options[:parameters].reverse_merge! :named_scope => scope
|
291
|
-
ActiveScaffold::DataStructures::ActionLink.new('index', options)
|
292
|
-
end
|
293
|
-
|
294
|
-
def add_active_scaffold_path(path)
|
295
|
-
as_path = File.join(ActiveScaffold::Config::Core.plugin_directory, 'app', 'views')
|
296
|
-
index = view_paths.find_index { |p| p.to_s == as_path }
|
297
|
-
if index
|
298
|
-
self.view_paths = view_paths[0..index-1] + Array(path) + view_paths[index..-1]
|
299
|
-
else
|
300
|
-
append_view_path path
|
301
|
-
end
|
302
|
-
end
|
303
|
-
|
304
|
-
def active_scaffold_config
|
305
|
-
if @active_scaffold_config.nil?
|
306
|
-
self.superclass.active_scaffold_config if self.superclass.respond_to? :active_scaffold_config
|
307
|
-
else
|
308
|
-
@active_scaffold_config
|
309
|
-
end
|
310
|
-
end
|
311
|
-
|
312
|
-
def active_scaffold_config_block
|
313
|
-
@active_scaffold_config_block
|
314
|
-
end
|
315
|
-
|
316
|
-
def active_scaffold_superclasses_blocks
|
317
|
-
blocks = []
|
318
|
-
klass = self.superclass
|
319
|
-
while klass.respond_to? :active_scaffold_superclasses_blocks
|
320
|
-
blocks << klass.active_scaffold_config_block
|
321
|
-
klass = klass.superclass
|
322
|
-
end
|
323
|
-
blocks.compact.reverse
|
324
|
-
end
|
325
|
-
|
326
|
-
def active_scaffold_config_for(klass)
|
327
|
-
begin
|
328
|
-
controller = active_scaffold_controller_for(klass)
|
329
|
-
rescue ActiveScaffold::ControllerNotFound
|
330
|
-
config = ActiveScaffold::Config::Core.new(klass)
|
331
|
-
config._load_action_columns
|
332
|
-
config
|
333
|
-
else
|
334
|
-
controller.active_scaffold_config
|
335
|
-
end
|
336
|
-
end
|
337
|
-
|
338
|
-
# Tries to find a controller for the given ActiveRecord model.
|
339
|
-
# Searches in the namespace of the current controller for singular and plural versions of the conventional "#{model}Controller" syntax.
|
340
|
-
# You may override this method to customize the search routine.
|
341
|
-
def active_scaffold_controller_for(klass)
|
342
|
-
controller_namespace = self.to_s.split('::')[0...-1].join('::') + '::'
|
343
|
-
error_message = []
|
344
|
-
[controller_namespace, ''].each do |namespace|
|
345
|
-
["#{klass.to_s.underscore.pluralize}", "#{klass.to_s.underscore.pluralize.singularize}"].each do |controller_name|
|
346
|
-
begin
|
347
|
-
controller = "#{namespace}#{controller_name.camelize}Controller".constantize
|
348
|
-
rescue NameError => error
|
349
|
-
# Only rescue NameError associated with the controller constant not existing - not other compile errors
|
350
|
-
if error.message["uninitialized constant #{controller}"]
|
351
|
-
error_message << "#{namespace}#{controller_name.camelize}Controller"
|
352
|
-
next
|
353
|
-
else
|
354
|
-
raise
|
355
|
-
end
|
356
|
-
end
|
357
|
-
raise ActiveScaffold::ControllerNotFound, "#{controller} missing ActiveScaffold", caller unless controller.uses_active_scaffold?
|
358
|
-
raise ActiveScaffold::ControllerNotFound, "ActiveScaffold on #{controller} is not for #{klass} model.", caller unless controller.active_scaffold_config.model.to_s == klass.to_s
|
359
|
-
return controller
|
360
|
-
end
|
361
|
-
end
|
362
|
-
raise ActiveScaffold::ControllerNotFound, "Could not find " + error_message.join(" or "), caller
|
363
|
-
end
|
364
|
-
|
365
|
-
def uses_active_scaffold?
|
366
|
-
!active_scaffold_config.nil?
|
367
|
-
end
|
88
|
+
def self.set_defaults(&block)
|
89
|
+
ActiveScaffold::Config::Core.configure &block
|
368
90
|
end
|
369
91
|
end
|
92
|
+
require 'active_scaffold/engine'
|
93
|
+
# TODO: clean up extensions. some could be organized for autoloading, and others could be removed entirely.
|
94
|
+
Dir["#{File.dirname __FILE__}/active_scaffold/extensions/*.rb"].each { |file| require file }
|
370
95
|
|
371
|
-
require 'active_scaffold_env'
|
@@ -1,26 +1,59 @@
|
|
1
1
|
module ActiveScaffold::Actions
|
2
2
|
module CommonSearch
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
def self.included(base)
|
4
|
+
unless base < InstanceMethods
|
5
|
+
base.send :include, InstanceMethods
|
6
|
+
base.before_filter :search_authorized_filter, :only => :show_search
|
7
|
+
base.before_filter :store_search_params_into_session, :only => [:index]
|
8
|
+
base.before_filter :do_search, :only => [:index]
|
9
|
+
base.helper_method :search_params
|
9
10
|
end
|
10
11
|
end
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
module InstanceMethods
|
14
|
+
def show_search
|
15
|
+
respond_to_action(search_partial || :search)
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
def do_search
|
20
|
+
end
|
21
|
+
|
22
|
+
def search_partial
|
23
|
+
@_search_partial ||= if params[:kind].present? && active_scaffold_config.actions.include?(params[:kind])
|
24
|
+
params.delete(:kind)
|
25
|
+
else
|
26
|
+
active_scaffold_config.list.auto_search_partial
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def store_search_params_into_session
|
31
|
+
if active_scaffold_config.store_user_settings
|
32
|
+
active_scaffold_session_storage[:search] = params.delete :search if params[:search]
|
33
|
+
else
|
34
|
+
@search_params = params.delete :search
|
35
|
+
end
|
36
|
+
end
|
15
37
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
38
|
+
def search_params
|
39
|
+
@search_params || active_scaffold_session_storage[:search]
|
40
|
+
end
|
41
|
+
|
42
|
+
def global_search_ignore?
|
43
|
+
active_scaffold_config.list.always_show_search == true
|
44
|
+
end
|
45
|
+
|
46
|
+
# The default security delegates to ActiveRecordPermissions.
|
47
|
+
# You may override the method to customize.
|
48
|
+
def search_authorized?
|
49
|
+
authorized_for?(:crud_type => :read)
|
50
|
+
end
|
51
|
+
|
52
|
+
def search_authorized_filter
|
53
|
+
action = active_scaffold_config.send(search_partial)
|
54
|
+
link = action.link || action.class.link
|
55
|
+
raise ActiveScaffold::ActionNotAllowed unless self.send(link.security_method)
|
56
|
+
end
|
24
57
|
end
|
25
58
|
end
|
26
59
|
end
|
@@ -2,13 +2,15 @@ module ActiveScaffold::Actions
|
|
2
2
|
module Core
|
3
3
|
def self.included(base)
|
4
4
|
base.class_eval do
|
5
|
-
|
5
|
+
before_filter :register_constraints_with_action_columns, :unless => :nested?
|
6
6
|
after_filter :clear_flashes
|
7
7
|
after_filter :clear_storage
|
8
8
|
rescue_from ActiveScaffold::RecordNotAllowed, ActiveScaffold::ActionNotAllowed, :with => :deny_access
|
9
9
|
end
|
10
10
|
base.helper_method :successful?
|
11
11
|
base.helper_method :nested?
|
12
|
+
base.helper_method :embedded?
|
13
|
+
base.helper_method :loading_embedded?
|
12
14
|
base.helper_method :calculate_query
|
13
15
|
base.helper_method :new_model
|
14
16
|
end
|
@@ -21,8 +23,12 @@ module ActiveScaffold::Actions
|
|
21
23
|
end
|
22
24
|
|
23
25
|
protected
|
26
|
+
def loading_embedded?
|
27
|
+
@loading_embedded ||= params.delete(:embedded)
|
28
|
+
end
|
29
|
+
|
24
30
|
def embedded?
|
25
|
-
|
31
|
+
params[:eid]
|
26
32
|
end
|
27
33
|
|
28
34
|
def nested?
|
@@ -39,9 +45,10 @@ module ActiveScaffold::Actions
|
|
39
45
|
@column = active_scaffold_config.columns[params.delete(:column)]
|
40
46
|
unless @column.nil?
|
41
47
|
@source_id = params.delete(:source_id)
|
42
|
-
@columns = @column.update_columns
|
48
|
+
@columns = @column.update_columns || []
|
43
49
|
@scope = params.delete(:scope)
|
44
50
|
@main_columns = active_scaffold_config.send(@scope ? :subform : (params[:id] ? :update : :create)).columns
|
51
|
+
@columns << @column.name if @column.options[:refresh_link] && @columns.exclude?(@column.name)
|
45
52
|
|
46
53
|
if @column.send_form_on_update_column
|
47
54
|
if @scope
|
@@ -53,17 +60,58 @@ module ActiveScaffold::Actions
|
|
53
60
|
hash = params[:record]
|
54
61
|
id = params[:id]
|
55
62
|
end
|
56
|
-
|
57
|
-
|
58
|
-
|
63
|
+
|
64
|
+
# check permissions and support overriding to_param
|
65
|
+
record = find_if_allowed(id, :update) if id
|
66
|
+
# call update_record_from_params with new_model
|
67
|
+
# in other case some associations can be saved
|
59
68
|
@record = new_model
|
69
|
+
copy_attributes(record, @record) if record
|
70
|
+
apply_constraints_to_record(@record) unless @scope
|
71
|
+
@record = update_record_from_params(@record, @main_columns, hash, true)
|
72
|
+
else
|
73
|
+
@record = params[:id] ? find_if_allowed(params[:id], :update) : new_model
|
74
|
+
if @record.new_record?
|
75
|
+
apply_constraints_to_record(@record) unless @scope
|
76
|
+
else
|
77
|
+
@record = @record.dup
|
78
|
+
end
|
60
79
|
value = column_value_from_param_value(@record, @column, params.delete(:value))
|
61
80
|
@record.send "#{@column.name}=", value
|
81
|
+
@record.id = params[:id]
|
62
82
|
end
|
83
|
+
set_parent(@record) if @record.id.nil? && params[:parent_controller] && params[:child_association]
|
63
84
|
|
64
85
|
after_render_field(@record, @column)
|
65
86
|
end
|
66
87
|
end
|
88
|
+
|
89
|
+
def set_parent(record)
|
90
|
+
parent_model = params[:parent_controller].singularize.camelize.constantize
|
91
|
+
association = parent_model.reflect_on_association(params[:child_association].to_sym).try(:reverse)
|
92
|
+
if association
|
93
|
+
parent = parent_model.new
|
94
|
+
copy_attributes(parent_model.find(params[:parent_id]), parent) if params[:parent_id]
|
95
|
+
parent.id = params[:parent_id]
|
96
|
+
parent = update_record_from_params(parent, active_scaffold_config_for(parent_model).send(params[:parent_id] ? :update : :create).columns, params[:record]) if @column.send_form_on_update_column
|
97
|
+
apply_constraints_to_record(parent) if params[:parent_id]
|
98
|
+
if record.class.reflect_on_association(association).collection?
|
99
|
+
record.send(association) << parent
|
100
|
+
else
|
101
|
+
record.send("#{association}=", parent)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def copy_attributes(orig, dst)
|
107
|
+
attributes = orig.attributes
|
108
|
+
if orig.class.respond_to? :protected_attributes
|
109
|
+
orig.class.protected_attributes.each { |attr| dst[attr] = orig[attr] }
|
110
|
+
attributes = attributes.except(*orig.class.protected_attributes)
|
111
|
+
end
|
112
|
+
dst.attributes = attributes
|
113
|
+
dst
|
114
|
+
end
|
67
115
|
|
68
116
|
# override this method if you want to do something after render_field
|
69
117
|
def after_render_field(record, column); end
|
@@ -134,19 +182,6 @@ module ActiveScaffold::Actions
|
|
134
182
|
def return_to_main
|
135
183
|
redirect_to main_path_to_return
|
136
184
|
end
|
137
|
-
|
138
|
-
# Override this method on your controller to define conditions to be used when querying a recordset (e.g. for List). The return of this method should be any format compatible with the :conditions clause of ActiveRecord::Base's find.
|
139
|
-
def conditions_for_collection
|
140
|
-
end
|
141
|
-
|
142
|
-
# Override this method on your controller to define joins to be used when querying a recordset (e.g. for List). The return of this method should be any format compatible with the :joins clause of ActiveRecord::Base's find.
|
143
|
-
def joins_for_collection
|
144
|
-
end
|
145
|
-
|
146
|
-
# Override this method on your controller to provide custom finder options to the find() call. The return of this method should be a hash.
|
147
|
-
def custom_finder_options
|
148
|
-
{}
|
149
|
-
end
|
150
185
|
|
151
186
|
#Overide this method on your controller to provide model with named scopes
|
152
187
|
def beginning_of_chain
|
@@ -157,13 +192,18 @@ module ActiveScaffold::Actions
|
|
157
192
|
def conditions_from_params
|
158
193
|
@conditions_from_params ||= begin
|
159
194
|
conditions = {}
|
160
|
-
params.except(:controller, :action, :page, :sort, :sort_direction).each do |key, value|
|
195
|
+
params.except(:controller, :action, :page, :sort, :sort_direction, :id).each do |key, value|
|
161
196
|
column = active_scaffold_config.model.columns_hash[key.to_s]
|
162
|
-
key = key.to_sym
|
163
197
|
next unless column
|
198
|
+
key = key.to_sym
|
199
|
+
not_string = [:string, :text].exclude?(column.type)
|
164
200
|
next if active_scaffold_constraints[key]
|
165
201
|
next if nested? and nested.param_name == key
|
166
|
-
conditions[key] =
|
202
|
+
conditions[key] = if value.is_a?(Array)
|
203
|
+
value.map {|v| v == '' && not_string ? nil : column.type_cast(v) }
|
204
|
+
else
|
205
|
+
value == '' && not_string ? nil : column.type_cast(value)
|
206
|
+
end
|
167
207
|
end
|
168
208
|
conditions
|
169
209
|
end
|
@@ -181,8 +221,39 @@ module ActiveScaffold::Actions
|
|
181
221
|
model.respond_to?(:build) ? model.build(build_options || {}) : model.new
|
182
222
|
end
|
183
223
|
|
224
|
+
def objects_for_etag
|
225
|
+
@last_modified ||= @record.updated_at
|
226
|
+
[@record, ('xhr' if request.xhr?)]
|
227
|
+
end
|
228
|
+
|
229
|
+
def view_stale?
|
230
|
+
objects = objects_for_etag
|
231
|
+
if objects.is_a?(Array)
|
232
|
+
args = {:etag => objects.to_a}
|
233
|
+
args[:last_modified] = @last_modified if @last_modified
|
234
|
+
elsif objects.is_a?(Hash)
|
235
|
+
args = {:last_modified => @last_modified}.merge(objects)
|
236
|
+
else
|
237
|
+
args = objects
|
238
|
+
end
|
239
|
+
stale?(args)
|
240
|
+
end
|
241
|
+
|
242
|
+
def conditional_get_support?
|
243
|
+
request.get? && active_scaffold_config.conditional_get_support
|
244
|
+
end
|
245
|
+
|
246
|
+
def virtual_columns(columns)
|
247
|
+
columns.reject {|col| active_scaffold_config.model.columns_hash[col] || active_scaffold_config.model.reflect_on_association(col)}
|
248
|
+
end
|
249
|
+
|
250
|
+
def association_columns(columns)
|
251
|
+
columns.select {|col| active_scaffold_config.model.reflect_on_association(col)}
|
252
|
+
end
|
253
|
+
|
184
254
|
private
|
185
255
|
def respond_to_action(action)
|
256
|
+
return unless !conditional_get_support? || view_stale?
|
186
257
|
respond_to do |type|
|
187
258
|
action_formats.each do |format|
|
188
259
|
type.send(format) do
|