active_scaffold 3.0.12 → 3.0.21
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/README +21 -11
- data/frontends/default/images/close_touch.png +0 -0
- data/frontends/default/javascripts/jquery/active_scaffold.js +187 -99
- data/frontends/default/javascripts/prototype/active_scaffold.js +105 -33
- data/frontends/default/javascripts/prototype/dhtml_history.js +80 -77
- data/frontends/default/stylesheets/stylesheet.css +121 -2
- data/frontends/default/views/_action_group.html.erb +6 -2
- data/frontends/default/views/_base_form.html.erb +11 -5
- data/frontends/default/views/_base_form.html.erb~ +42 -0
- data/frontends/default/views/_field_search.html.erb +1 -1
- data/frontends/default/views/_form.html.erb +9 -7
- data/frontends/default/views/_form_association.html.erb +8 -3
- data/frontends/default/views/_form_association_footer.html.erb +10 -3
- data/frontends/default/views/_form_attribute.html.erb +8 -3
- data/frontends/default/views/_horizontal_subform.html.erb +12 -2
- data/frontends/default/views/_horizontal_subform_header.html.erb +1 -1
- data/frontends/default/views/_horizontal_subform_record.html.erb +5 -4
- data/frontends/default/views/_list_messages.html.erb +1 -1
- data/frontends/default/views/_list_with_header.html.erb +1 -1
- data/frontends/default/views/_render_field.js.rjs +4 -6
- data/frontends/default/views/_vertical_subform.html.erb +1 -1
- data/frontends/default/views/_vertical_subform_record.html.erb +2 -2
- data/frontends/default/views/on_action_update.js.rjs +3 -1
- data/frontends/default/views/on_mark_all.js.rjs +12 -0
- data/frontends/default/views/on_update.js.rjs +1 -1
- data/frontends/default/views/render_field.js.rjs +1 -0
- data/frontends/default/views/update_column.js.rjs +1 -1
- data/lib/active_scaffold.rb +60 -21
- data/lib/active_scaffold/actions/common_search.rb +2 -2
- data/lib/active_scaffold/actions/core.rb +30 -9
- data/lib/active_scaffold/actions/create.rb +14 -10
- data/lib/active_scaffold/actions/field_search.rb +6 -6
- data/lib/active_scaffold/actions/list.rb +22 -12
- data/lib/active_scaffold/actions/mark.rb +34 -9
- data/lib/active_scaffold/actions/nested.rb +12 -16
- data/lib/active_scaffold/actions/show.rb +2 -2
- data/lib/active_scaffold/actions/subform.rb +15 -8
- data/lib/active_scaffold/actions/update.rb +14 -4
- data/lib/active_scaffold/attribute_params.rb +15 -10
- data/lib/active_scaffold/bridges/bridge.rb +21 -12
- data/lib/active_scaffold/bridges/calendar_date_select/bridge.rb +3 -3
- data/lib/active_scaffold/bridges/cancan/bridge.rb +12 -0
- data/lib/active_scaffold/bridges/cancan/lib/cancan_bridge.rb +107 -0
- data/lib/active_scaffold/bridges/carrierwave/bridge.rb +1 -1
- data/lib/active_scaffold/bridges/carrierwave/lib/carrierwave_bridge.rb +3 -8
- data/lib/active_scaffold/bridges/carrierwave/lib/carrierwave_bridge_helpers.rb +1 -15
- data/lib/active_scaffold/bridges/carrierwave/lib/form_ui.rb +23 -13
- data/lib/active_scaffold/bridges/carrierwave/lib/list_ui.rb +1 -1
- data/lib/active_scaffold/bridges/country_helper/bridge.rb +9 -0
- data/lib/active_scaffold/bridges/country_helper/lib/country_helper_bridge.rb +358 -0
- data/lib/active_scaffold/bridges/date_picker/bridge.rb +5 -3
- data/lib/active_scaffold/bridges/date_picker/lib/datepicker_bridge.rb +9 -0
- data/lib/active_scaffold/bridges/dragonfly/bridge.rb +9 -0
- data/lib/active_scaffold/bridges/dragonfly/bridge.rb~ +12 -0
- data/lib/active_scaffold/bridges/dragonfly/lib/dragonfly_bridge.rb +36 -0
- data/lib/active_scaffold/bridges/dragonfly/lib/dragonfly_bridge.rb~ +36 -0
- data/lib/active_scaffold/bridges/dragonfly/lib/dragonfly_bridge_helpers.rb +12 -0
- data/lib/active_scaffold/bridges/dragonfly/lib/dragonfly_bridge_helpers.rb~ +12 -0
- data/lib/active_scaffold/bridges/dragonfly/lib/form_ui.rb +27 -0
- data/lib/active_scaffold/bridges/dragonfly/lib/form_ui.rb~ +27 -0
- data/lib/active_scaffold/bridges/dragonfly/lib/list_ui.rb +16 -0
- data/lib/active_scaffold/bridges/dragonfly/lib/list_ui.rb~ +16 -0
- data/lib/active_scaffold/bridges/paperclip/bridge.rb +1 -1
- data/lib/active_scaffold/bridges/record_select/bridge.rb +5 -0
- data/lib/active_scaffold/bridges/record_select/lib/record_select_bridge.rb +87 -0
- data/lib/active_scaffold/bridges/record_select/lib/record_select_bridge.rb~ +84 -0
- data/lib/active_scaffold/bridges/shared/date_bridge.rb +56 -34
- data/lib/active_scaffold/bridges/tiny_mce/lib/tiny_mce_bridge.rb +19 -3
- data/lib/active_scaffold/config/base.rb +4 -4
- data/lib/active_scaffold/config/core.rb +4 -0
- data/lib/active_scaffold/config/create.rb +1 -1
- data/lib/active_scaffold/config/field_search.rb +7 -7
- data/lib/active_scaffold/config/form.rb +8 -2
- data/lib/active_scaffold/config/list.rb +22 -8
- data/lib/active_scaffold/config/mark.rb +18 -5
- data/lib/active_scaffold/config/nested.rb +3 -3
- data/lib/active_scaffold/config/search.rb +1 -1
- data/lib/active_scaffold/config/show.rb +1 -1
- data/lib/active_scaffold/data_structures/action_columns.rb +10 -6
- data/lib/active_scaffold/data_structures/action_link.rb +14 -10
- data/lib/active_scaffold/data_structures/action_links.rb +2 -2
- data/lib/active_scaffold/data_structures/column.rb +25 -11
- data/lib/active_scaffold/data_structures/nested_info.rb +21 -21
- data/lib/active_scaffold/data_structures/set.rb +2 -3
- data/lib/active_scaffold/data_structures/sorting.rb +8 -8
- data/lib/{extensions → active_scaffold/extensions}/action_controller_rendering.rb +3 -1
- data/lib/{extensions → active_scaffold/extensions}/action_view_rendering.rb +31 -33
- data/lib/{extensions → active_scaffold/extensions}/action_view_resolver.rb +0 -0
- data/lib/{extensions → active_scaffold/extensions}/active_association_reflection.rb +0 -0
- data/lib/active_scaffold/extensions/active_record_offset.rb +12 -0
- data/lib/{extensions → active_scaffold/extensions}/array.rb +0 -0
- data/lib/{extensions → active_scaffold/extensions}/localize.rb +1 -1
- data/lib/{extensions → active_scaffold/extensions}/name_option_for_datetime.rb +1 -1
- data/lib/{extensions → active_scaffold/extensions}/nil_id_in_url_params.rb +0 -0
- data/lib/{extensions → active_scaffold/extensions}/paginator_extensions.rb +2 -2
- data/lib/{extensions → active_scaffold/extensions}/reverse_associations.rb +1 -1
- data/lib/{extensions → active_scaffold/extensions}/routing_mapper.rb +2 -2
- data/lib/{extensions → active_scaffold/extensions}/to_label.rb +0 -0
- data/lib/{extensions → active_scaffold/extensions}/unsaved_associated.rb +0 -0
- data/lib/{extensions → active_scaffold/extensions}/unsaved_record.rb +0 -0
- data/lib/active_scaffold/extensions/usa_state.rb +46 -0
- data/lib/active_scaffold/finder.rb +30 -19
- data/lib/active_scaffold/helpers/controller_helpers.rb +3 -5
- data/lib/active_scaffold/helpers/form_column_helpers.rb +19 -45
- data/lib/active_scaffold/helpers/human_condition_helpers.rb +1 -1
- data/lib/active_scaffold/helpers/id_helpers.rb +2 -2
- data/lib/active_scaffold/helpers/list_column_helpers.rb +28 -17
- data/lib/active_scaffold/helpers/search_column_helpers.rb +51 -40
- data/lib/active_scaffold/helpers/search_column_helpers.rb~ +215 -0
- data/lib/active_scaffold/helpers/show_column_helpers.rb +8 -4
- data/lib/active_scaffold/helpers/view_helpers.rb +50 -27
- data/lib/active_scaffold/locale/de.yml +111 -0
- data/lib/active_scaffold/locale/en.yml +115 -0
- data/lib/active_scaffold/locale/es.yml +32 -32
- data/lib/active_scaffold/locale/fr.yml +118 -0
- data/lib/active_scaffold/marked_model.rb +6 -6
- data/lib/active_scaffold/version.rb +1 -1
- data/lib/active_scaffold_assets.rb +1 -3
- data/lib/active_scaffold_env.rb +1 -2
- data/lib/generators/active_scaffold/active_scaffold_generator.rb +5 -5
- data/lib/generators/active_scaffold_controller/active_scaffold_controller_generator.rb +3 -2
- data/lib/generators/active_scaffold_controller/templates/helper.rb +2 -0
- data/lib/generators/active_scaffold_setup/active_scaffold_setup_generator.rb +17 -19
- data/shoulda_macros/macros.rb +4 -4
- data/test/misc/finder_test.rb +2 -2
- data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet.css +4 -1
- metadata +144 -126
- data/.autotest +0 -27
- data/.document +0 -5
- data/Gemfile +0 -13
- data/Gemfile.lock +0 -20
- data/Rakefile +0 -53
- data/active_scaffold.gemspec +0 -385
- data/init.rb +0 -2
- data/lib/active_scaffold/helpers/country_helpers.rb +0 -358
- data/lib/active_scaffold/locale/de.rb +0 -120
- data/lib/active_scaffold/locale/en.rb +0 -119
- data/lib/active_scaffold/locale/fr.rb +0 -116
- data/lib/extensions/active_record_offset.rb +0 -12
- data/lib/extensions/usa_state.rb +0 -50
- data/test/mock_app/.gitignore +0 -2
- data/uninstall.rb +0 -13
|
@@ -18,7 +18,7 @@ module ActiveScaffold::Actions
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
protected
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
def show_respond_to_json
|
|
23
23
|
render :text => response_object.to_json(:only => active_scaffold_config.show.columns.names), :content_type => Mime::JSON, :status => response_status
|
|
24
24
|
end
|
|
@@ -49,7 +49,7 @@ module ActiveScaffold::Actions
|
|
|
49
49
|
def show_authorized?(record = nil)
|
|
50
50
|
authorized_for?(:crud_type => :read)
|
|
51
51
|
end
|
|
52
|
-
private
|
|
52
|
+
private
|
|
53
53
|
def show_authorized_filter
|
|
54
54
|
link = active_scaffold_config.show.link || active_scaffold_config.show.class.link
|
|
55
55
|
raise ActiveScaffold::ActionNotAllowed unless self.send(link.security_method)
|
|
@@ -1,20 +1,27 @@
|
|
|
1
1
|
module ActiveScaffold::Actions
|
|
2
2
|
module Subform
|
|
3
3
|
def edit_associated
|
|
4
|
-
|
|
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)
|
|
5
12
|
@column = active_scaffold_config.columns[params[:association]]
|
|
6
13
|
|
|
7
|
-
# NOTE: we don't check whether the user is allowed to update
|
|
8
|
-
# this record, because if not, we'll still let them associate
|
|
9
|
-
# the record. we'll just refuse to do more than associate, is
|
|
10
|
-
# all.
|
|
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.
|
|
11
15
|
@record = @column.association.klass.find(params[:associated_id]) if params[:associated_id]
|
|
12
|
-
@record ||= @column.
|
|
16
|
+
@record ||= if @column.singular_association?
|
|
17
|
+
@parent_record.send("build_#{@column.name}".to_sym)
|
|
18
|
+
else
|
|
19
|
+
@parent_record.send(@column.name).build
|
|
20
|
+
end
|
|
13
21
|
|
|
14
22
|
@scope = "[#{@column.name}]"
|
|
15
23
|
@scope += (@record.new_record?) ? "[#{(Time.now.to_f*1000).to_i.to_s}]" : "[#{@record.id}]" if @column.plural_association?
|
|
16
|
-
|
|
17
|
-
render :action => 'edit_associated'
|
|
18
24
|
end
|
|
25
|
+
|
|
19
26
|
end
|
|
20
27
|
end
|
|
@@ -5,6 +5,7 @@ module ActiveScaffold::Actions
|
|
|
5
5
|
base.verify :method => [:post, :put],
|
|
6
6
|
:only => :update,
|
|
7
7
|
:redirect_to => { :action => :index }
|
|
8
|
+
base.helper_method :update_refresh_list?
|
|
8
9
|
end
|
|
9
10
|
|
|
10
11
|
def edit
|
|
@@ -34,7 +35,7 @@ module ActiveScaffold::Actions
|
|
|
34
35
|
def edit_respond_to_js
|
|
35
36
|
render(:partial => 'update_form')
|
|
36
37
|
end
|
|
37
|
-
def update_respond_to_html
|
|
38
|
+
def update_respond_to_html
|
|
38
39
|
if params[:iframe]=='true' # was this an iframe post ?
|
|
39
40
|
responds_to_parent do
|
|
40
41
|
render :action => 'on_update.js', :layout => false
|
|
@@ -49,7 +50,7 @@ module ActiveScaffold::Actions
|
|
|
49
50
|
end
|
|
50
51
|
end
|
|
51
52
|
def update_respond_to_js
|
|
52
|
-
if successful? &&
|
|
53
|
+
if successful? && update_refresh_list? && !render_parent?
|
|
53
54
|
do_search if respond_to? :do_search
|
|
54
55
|
do_list
|
|
55
56
|
end
|
|
@@ -75,18 +76,22 @@ module ActiveScaffold::Actions
|
|
|
75
76
|
# If you want to customize this algorithm, consider using the +before_update_save+ callback
|
|
76
77
|
def do_update
|
|
77
78
|
do_edit
|
|
78
|
-
@record = update_record_from_params(@record, active_scaffold_config.update.columns, params[:record])
|
|
79
79
|
update_save
|
|
80
80
|
end
|
|
81
81
|
|
|
82
|
-
def update_save
|
|
82
|
+
def update_save(options = {})
|
|
83
83
|
begin
|
|
84
84
|
active_scaffold_config.model.transaction do
|
|
85
|
+
@record = update_record_from_params(@record, active_scaffold_config.update.columns, params[:record]) unless options[:no_record_param_update]
|
|
85
86
|
before_update_save(@record)
|
|
86
87
|
self.successful = [@record.valid?, @record.associated_valid?].all? {|v| v == true} # this syntax avoids a short-circuit
|
|
87
88
|
if successful?
|
|
88
89
|
@record.save! and @record.save_associated!
|
|
89
90
|
after_update_save(@record)
|
|
91
|
+
else
|
|
92
|
+
# some associations such as habtm are saved before saved is called on parent object
|
|
93
|
+
# we have to revert these changes if validation fails
|
|
94
|
+
raise ActiveRecord::Rollback, "don't save habtm associations unless record is valid"
|
|
90
95
|
end
|
|
91
96
|
end
|
|
92
97
|
rescue ActiveRecord::RecordInvalid
|
|
@@ -121,6 +126,11 @@ module ActiveScaffold::Actions
|
|
|
121
126
|
# override this method if you want to do something after the save
|
|
122
127
|
def after_update_save(record); end
|
|
123
128
|
|
|
129
|
+
# should we refresh whole list after update operation
|
|
130
|
+
def update_refresh_list?
|
|
131
|
+
active_scaffold_config.update.refresh_list
|
|
132
|
+
end
|
|
133
|
+
|
|
124
134
|
# The default security delegates to ActiveRecordPermissions.
|
|
125
135
|
# You may override the method to customize.
|
|
126
136
|
def update_authorized?(record = nil)
|
|
@@ -39,6 +39,7 @@ module ActiveScaffold
|
|
|
39
39
|
crud_type = parent_record.new_record? ? :create : :update
|
|
40
40
|
return parent_record unless parent_record.authorized_for?(:crud_type => crud_type)
|
|
41
41
|
|
|
42
|
+
attributes = {} unless attributes.is_a?(Hash)
|
|
42
43
|
multi_parameter_attributes = {}
|
|
43
44
|
attributes.each do |k, v|
|
|
44
45
|
next unless k.include? '('
|
|
@@ -56,11 +57,11 @@ module ActiveScaffold
|
|
|
56
57
|
if multi_parameter_attributes.has_key? column.name
|
|
57
58
|
parent_record.send(:assign_multiparameter_attributes, multi_parameter_attributes[column.name])
|
|
58
59
|
elsif attributes.has_key? column.name
|
|
59
|
-
value = column_value_from_param_value(parent_record, column, attributes[column.name])
|
|
60
|
+
value = column_value_from_param_value(parent_record, column, attributes[column.name])
|
|
60
61
|
|
|
61
62
|
# we avoid assigning a value that already exists because otherwise has_one associations will break (AR bug in has_one_association.rb#replace)
|
|
62
63
|
parent_record.send("#{column.name}=", value) unless parent_record.send(column.name) == value
|
|
63
|
-
|
|
64
|
+
|
|
64
65
|
# plural associations may not actually appear in the params if all of the options have been unselected or cleared away.
|
|
65
66
|
# the "form_ui" check is necessary, becuase without it we have problems
|
|
66
67
|
# with subforms. the UI cuts out deep associations, which means they're not present in the
|
|
@@ -85,7 +86,7 @@ module ActiveScaffold
|
|
|
85
86
|
|
|
86
87
|
parent_record
|
|
87
88
|
end
|
|
88
|
-
|
|
89
|
+
|
|
89
90
|
def manage_nested_record_from_params(parent_record, column, attributes)
|
|
90
91
|
record = find_or_create_for_params(attributes, column, parent_record)
|
|
91
92
|
if record
|
|
@@ -95,7 +96,7 @@ module ActiveScaffold
|
|
|
95
96
|
end
|
|
96
97
|
record
|
|
97
98
|
end
|
|
98
|
-
|
|
99
|
+
|
|
99
100
|
def column_value_from_param_value(parent_record, column, value)
|
|
100
101
|
# convert the value, possibly by instantiating associated objects
|
|
101
102
|
if value.is_a?(Hash)
|
|
@@ -110,12 +111,8 @@ module ActiveScaffold
|
|
|
110
111
|
# it's a single id
|
|
111
112
|
column.association.klass.find(value) if value and not value.empty?
|
|
112
113
|
elsif column.plural_association?
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
ids = value.select {|id| id.respond_to?(:empty?) ? !id.empty? : true}
|
|
116
|
-
ids.empty? ? [] : column.association.klass.find(ids)
|
|
117
|
-
end
|
|
118
|
-
elsif column.column && column.column.number? && [:i18n_number, :currency].include?(column.options[:format])
|
|
114
|
+
column_plural_assocation_value_from_value(column, value)
|
|
115
|
+
elsif column.column && column.number? && [:i18n_number, :currency].include?(column.options[:format])
|
|
119
116
|
self.class.i18n_number_to_native_format(value)
|
|
120
117
|
else
|
|
121
118
|
# convert empty strings into nil. this works better with 'null => true' columns (and validations),
|
|
@@ -126,6 +123,14 @@ module ActiveScaffold
|
|
|
126
123
|
end
|
|
127
124
|
end
|
|
128
125
|
|
|
126
|
+
def column_plural_assocation_value_from_value(column, value)
|
|
127
|
+
# it's an array of ids
|
|
128
|
+
if value and not value.empty?
|
|
129
|
+
ids = value.select {|id| id.respond_to?(:empty?) ? !id.empty? : true}
|
|
130
|
+
ids.empty? ? [] : column.association.klass.find(ids)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
129
134
|
def column_value_from_param_hash_value(parent_record, column, value)
|
|
130
135
|
# this is just for backwards compatibility. we should clean this up in 2.0.
|
|
131
136
|
if column.form_ui == :select
|
|
@@ -3,42 +3,45 @@ module ActiveScaffold
|
|
|
3
3
|
def self.bridge(name, &block)
|
|
4
4
|
ActiveScaffold::Bridges::Bridge.new(name, &block)
|
|
5
5
|
end
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
class Bridge
|
|
8
8
|
attr_accessor :name
|
|
9
9
|
cattr_accessor :bridges
|
|
10
10
|
cattr_accessor :bridges_run
|
|
11
11
|
self.bridges = []
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
def initialize(name, &block)
|
|
14
14
|
self.name = name
|
|
15
15
|
@install = nil
|
|
16
16
|
# by convention and default, use the bridge name as the required constant for installation
|
|
17
17
|
@install_if = lambda { Object.const_defined?(name) }
|
|
18
18
|
self.instance_eval(&block)
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
ActiveScaffold::Bridges::Bridge.bridges << self
|
|
21
21
|
end
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
# Set the install block
|
|
24
24
|
def install(&block)
|
|
25
25
|
@install = block
|
|
26
26
|
end
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
# Set the install_if block (to check to see whether or not to install the block)
|
|
29
29
|
def install?(&block)
|
|
30
30
|
@install_if = block
|
|
31
31
|
end
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
|
|
33
|
+
|
|
34
34
|
def run
|
|
35
35
|
raise(ArgumentError, "install and install? not defined for bridge #{name}" ) unless @install && @install_if
|
|
36
36
|
@install.call if @install_if.call
|
|
37
37
|
end
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
def self.run_all
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
return false if self.bridges_run
|
|
41
|
+
ActiveScaffold::Bridges::Bridge.bridges.each{|bridge|
|
|
42
|
+
bridge.run
|
|
43
|
+
}
|
|
44
|
+
self.bridges_run=true
|
|
42
45
|
end
|
|
43
46
|
end
|
|
44
47
|
end
|
|
@@ -46,5 +49,11 @@ end
|
|
|
46
49
|
|
|
47
50
|
require File.join(File.dirname(__FILE__), 'shared', 'date_bridge.rb')
|
|
48
51
|
Dir[File.join(File.dirname(__FILE__), "*/bridge.rb")].each{|bridge_require|
|
|
49
|
-
|
|
50
|
-
|
|
52
|
+
load_bridge = true
|
|
53
|
+
unless ActiveScaffold.exclude_bridges.empty?
|
|
54
|
+
match = bridge_require.match('bridges\/(.*)\/bridge.rb')
|
|
55
|
+
bridge_name = match[1] ? match[1] : nil
|
|
56
|
+
load_bridge = ActiveScaffold.exclude_bridges.exclude?(bridge_name.to_sym) if bridge_name
|
|
57
|
+
end
|
|
58
|
+
require bridge_require if load_bridge == true
|
|
59
|
+
}
|
|
@@ -2,14 +2,14 @@ ActiveScaffold::Bridges.bridge "CalendarDateSelect" do
|
|
|
2
2
|
install do
|
|
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
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
|
+
|
|
10
10
|
require File.join(File.dirname(__FILE__), "lib/as_cds_bridge.rb")
|
|
11
11
|
end
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
install? do
|
|
14
14
|
Object.const_defined?(name) && ActiveScaffold.js_framework == :prototype
|
|
15
15
|
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
ActiveScaffold::Bridges.bridge "CanCan" do
|
|
2
|
+
install do
|
|
3
|
+
require File.join(File.dirname(__FILE__), "lib", "cancan_bridge.rb")
|
|
4
|
+
|
|
5
|
+
ActiveScaffold::ClassMethods.send :include, ActiveScaffold::CancanBridge::ClassMethods
|
|
6
|
+
ActiveScaffold::Actions::Core.send :include, ActiveScaffold::CancanBridge::Actions::Core
|
|
7
|
+
ActiveScaffold::Actions::Nested.send :include, ActiveScaffold::CancanBridge::Actions::Core
|
|
8
|
+
ActionController::Base.send :include, ActiveScaffold::CancanBridge::ModelUserAccess::Controller
|
|
9
|
+
ActiveRecord::Base.send :include, ActiveScaffold::CancanBridge::ModelUserAccess::Model
|
|
10
|
+
ActiveRecord::Base.send :include, ActiveScaffold::CancanBridge::ActiveRecord
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
module ActiveScaffold
|
|
2
|
+
module CancanBridge
|
|
3
|
+
|
|
4
|
+
# controller level authorization
|
|
5
|
+
# As already has callbacks to ensure authorization at controller method via "authorization_method"
|
|
6
|
+
# but let's include this too, just in case, no sure how performance is affected tough :TODO benchmark
|
|
7
|
+
module ClassMethods
|
|
8
|
+
extend ActiveSupport::Concern
|
|
9
|
+
included do
|
|
10
|
+
alias_method_chain :active_scaffold, :cancan
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def active_scaffold_with_cancan(model_id = nil, &block)
|
|
14
|
+
active_scaffold_without_cancan(model_id, &block)
|
|
15
|
+
authorize_resource(
|
|
16
|
+
:class => active_scaffold_config.model,
|
|
17
|
+
:instance => :record
|
|
18
|
+
)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# beginning of chain integration
|
|
23
|
+
module Actions
|
|
24
|
+
module Core
|
|
25
|
+
extend ActiveSupport::Concern
|
|
26
|
+
included do
|
|
27
|
+
alias_method_chain :beginning_of_chain, :cancan
|
|
28
|
+
end
|
|
29
|
+
# :TODO can this be expanded more ?
|
|
30
|
+
def beginning_of_chain_with_cancan
|
|
31
|
+
beginning_of_chain_without_cancan.accessible_by(current_ability)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# This is a module aimed at making the current_ability available to ActiveRecord models for permissions.
|
|
37
|
+
module ModelUserAccess
|
|
38
|
+
module Controller
|
|
39
|
+
extend ActiveSupport::Concern
|
|
40
|
+
included do
|
|
41
|
+
prepend_before_filter :assign_current_ability_to_models
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# We need to give the ActiveRecord classes a handle to the current ability. We don't want to just pass the object,
|
|
45
|
+
# because the object may change (someone may log in or out). So we give ActiveRecord a proc that ties to the
|
|
46
|
+
# current_ability_method on this ApplicationController.
|
|
47
|
+
def assign_current_ability_to_models
|
|
48
|
+
::ActiveRecord::Base.current_ability_proc = proc {send(:current_ability)}
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
module Model
|
|
53
|
+
extend ActiveSupport::Concern
|
|
54
|
+
|
|
55
|
+
module ClassMethods
|
|
56
|
+
# The proc to call that retrieves the current_ability from the ApplicationController.
|
|
57
|
+
attr_accessor :current_ability_proc
|
|
58
|
+
|
|
59
|
+
# Class-level access to the current ability
|
|
60
|
+
def current_ability
|
|
61
|
+
::ActiveRecord::Base.current_ability_proc.call if ::ActiveRecord::Base.current_ability_proc
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Instance-level access to the current ability
|
|
66
|
+
def current_ability; self.class.current_ability end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# plug into AS#authorized_for calls
|
|
72
|
+
module ActiveRecord
|
|
73
|
+
extend ActiveSupport::Concern
|
|
74
|
+
included do
|
|
75
|
+
extend SecurityMethods
|
|
76
|
+
include SecurityMethods
|
|
77
|
+
alias_method_chain :authorized_for?, :cancan
|
|
78
|
+
class << self
|
|
79
|
+
alias_method_chain :authorized_for?, :cancan
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
module SecurityMethods
|
|
84
|
+
class InvalidArgument < StandardError; end
|
|
85
|
+
|
|
86
|
+
# is usually called with :crud_type and :column, or :action
|
|
87
|
+
# {:crud_type=>:update, :column=>"some_colum_name"}
|
|
88
|
+
# {:action=>"edit"}
|
|
89
|
+
# to allow access cancan must allow both :crud_type and :action
|
|
90
|
+
# if cancan says "no", it delegates to default AS behavior
|
|
91
|
+
def authorized_for_with_cancan?(options = {})
|
|
92
|
+
raise InvalidArgument if options[:crud_type].blank? and options[:action].blank?
|
|
93
|
+
if current_ability.present?
|
|
94
|
+
crud_type_result = options[:crud_type].nil? ? true : current_ability.can?(options[:crud_type], self)
|
|
95
|
+
action_result = options[:action].nil? ? true : current_ability.can?(options[:action].to_sym, self)
|
|
96
|
+
else
|
|
97
|
+
crud_type_result, action_result = false, false
|
|
98
|
+
end
|
|
99
|
+
default_result = authorized_for_without_cancan?(options)
|
|
100
|
+
result = (crud_type_result && action_result) || default_result
|
|
101
|
+
return result
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -12,8 +12,6 @@ module ActiveScaffold
|
|
|
12
12
|
|
|
13
13
|
self.model.uploaders.keys.each do |field|
|
|
14
14
|
configure_carrierwave_field(field.to_sym)
|
|
15
|
-
# define the "delete" helper for use with active scaffold, unless it's already defined
|
|
16
|
-
ActiveScaffold::Bridges::Carrierwave::Lib::CarrierwaveBridgeHelpers.generate_delete_helper(self.model, field)
|
|
17
15
|
end
|
|
18
16
|
end
|
|
19
17
|
|
|
@@ -24,12 +22,9 @@ module ActiveScaffold
|
|
|
24
22
|
private
|
|
25
23
|
def configure_carrierwave_field(field)
|
|
26
24
|
self.columns << field
|
|
27
|
-
self.columns[field].form_ui ||= :carrierwave
|
|
28
|
-
self.columns[field].params.add "
|
|
29
|
-
|
|
30
|
-
# [:file_name, :content_type, :file_size, :updated_at].each do |f|
|
|
31
|
-
# self.columns.exclude("#{field}_#{f}".to_sym)
|
|
32
|
-
# end
|
|
25
|
+
self.columns[field].form_ui ||= :carrierwave # :TODO thumbnail
|
|
26
|
+
self.columns[field].params.add "#{field}_cache"
|
|
27
|
+
self.columns[field].params.add "remove_#{field}"
|
|
33
28
|
end
|
|
34
29
|
end
|
|
35
30
|
end
|
|
@@ -5,22 +5,8 @@ module ActiveScaffold
|
|
|
5
5
|
module CarrierwaveBridgeHelpers
|
|
6
6
|
mattr_accessor :thumbnail_style
|
|
7
7
|
self.thumbnail_style = :thumbnail
|
|
8
|
-
|
|
9
|
-
def self.generate_delete_helper(klass, field)
|
|
10
|
-
klass.class_eval <<-EOF, __FILE__, __LINE__ + 1 unless klass.methods.include?("delete_#{field}=")
|
|
11
|
-
attr_reader :delete_#{field}
|
|
12
|
-
|
|
13
|
-
def delete_#{field}=(value)
|
|
14
|
-
value = (value == "true") if String === value
|
|
15
|
-
return unless value
|
|
16
|
-
|
|
17
|
-
# passing nil to the file column causes the file to be deleted. Don't delete if we just uploaded a file!
|
|
18
|
-
self.remove_#{field}! unless new_record?
|
|
19
|
-
end
|
|
20
|
-
EOF
|
|
21
|
-
end
|
|
22
8
|
end
|
|
23
9
|
end
|
|
24
10
|
end
|
|
25
11
|
end
|
|
26
|
-
end
|
|
12
|
+
end
|