active_scaffold 3.0.12 → 3.0.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. data/README +21 -11
  2. data/frontends/default/images/close_touch.png +0 -0
  3. data/frontends/default/javascripts/jquery/active_scaffold.js +187 -99
  4. data/frontends/default/javascripts/prototype/active_scaffold.js +105 -33
  5. data/frontends/default/javascripts/prototype/dhtml_history.js +80 -77
  6. data/frontends/default/stylesheets/stylesheet.css +121 -2
  7. data/frontends/default/views/_action_group.html.erb +6 -2
  8. data/frontends/default/views/_base_form.html.erb +11 -5
  9. data/frontends/default/views/_base_form.html.erb~ +42 -0
  10. data/frontends/default/views/_field_search.html.erb +1 -1
  11. data/frontends/default/views/_form.html.erb +9 -7
  12. data/frontends/default/views/_form_association.html.erb +8 -3
  13. data/frontends/default/views/_form_association_footer.html.erb +10 -3
  14. data/frontends/default/views/_form_attribute.html.erb +8 -3
  15. data/frontends/default/views/_horizontal_subform.html.erb +12 -2
  16. data/frontends/default/views/_horizontal_subform_header.html.erb +1 -1
  17. data/frontends/default/views/_horizontal_subform_record.html.erb +5 -4
  18. data/frontends/default/views/_list_messages.html.erb +1 -1
  19. data/frontends/default/views/_list_with_header.html.erb +1 -1
  20. data/frontends/default/views/_render_field.js.rjs +4 -6
  21. data/frontends/default/views/_vertical_subform.html.erb +1 -1
  22. data/frontends/default/views/_vertical_subform_record.html.erb +2 -2
  23. data/frontends/default/views/on_action_update.js.rjs +3 -1
  24. data/frontends/default/views/on_mark_all.js.rjs +12 -0
  25. data/frontends/default/views/on_update.js.rjs +1 -1
  26. data/frontends/default/views/render_field.js.rjs +1 -0
  27. data/frontends/default/views/update_column.js.rjs +1 -1
  28. data/lib/active_scaffold.rb +60 -21
  29. data/lib/active_scaffold/actions/common_search.rb +2 -2
  30. data/lib/active_scaffold/actions/core.rb +30 -9
  31. data/lib/active_scaffold/actions/create.rb +14 -10
  32. data/lib/active_scaffold/actions/field_search.rb +6 -6
  33. data/lib/active_scaffold/actions/list.rb +22 -12
  34. data/lib/active_scaffold/actions/mark.rb +34 -9
  35. data/lib/active_scaffold/actions/nested.rb +12 -16
  36. data/lib/active_scaffold/actions/show.rb +2 -2
  37. data/lib/active_scaffold/actions/subform.rb +15 -8
  38. data/lib/active_scaffold/actions/update.rb +14 -4
  39. data/lib/active_scaffold/attribute_params.rb +15 -10
  40. data/lib/active_scaffold/bridges/bridge.rb +21 -12
  41. data/lib/active_scaffold/bridges/calendar_date_select/bridge.rb +3 -3
  42. data/lib/active_scaffold/bridges/cancan/bridge.rb +12 -0
  43. data/lib/active_scaffold/bridges/cancan/lib/cancan_bridge.rb +107 -0
  44. data/lib/active_scaffold/bridges/carrierwave/bridge.rb +1 -1
  45. data/lib/active_scaffold/bridges/carrierwave/lib/carrierwave_bridge.rb +3 -8
  46. data/lib/active_scaffold/bridges/carrierwave/lib/carrierwave_bridge_helpers.rb +1 -15
  47. data/lib/active_scaffold/bridges/carrierwave/lib/form_ui.rb +23 -13
  48. data/lib/active_scaffold/bridges/carrierwave/lib/list_ui.rb +1 -1
  49. data/lib/active_scaffold/bridges/country_helper/bridge.rb +9 -0
  50. data/lib/active_scaffold/bridges/country_helper/lib/country_helper_bridge.rb +358 -0
  51. data/lib/active_scaffold/bridges/date_picker/bridge.rb +5 -3
  52. data/lib/active_scaffold/bridges/date_picker/lib/datepicker_bridge.rb +9 -0
  53. data/lib/active_scaffold/bridges/dragonfly/bridge.rb +9 -0
  54. data/lib/active_scaffold/bridges/dragonfly/bridge.rb~ +12 -0
  55. data/lib/active_scaffold/bridges/dragonfly/lib/dragonfly_bridge.rb +36 -0
  56. data/lib/active_scaffold/bridges/dragonfly/lib/dragonfly_bridge.rb~ +36 -0
  57. data/lib/active_scaffold/bridges/dragonfly/lib/dragonfly_bridge_helpers.rb +12 -0
  58. data/lib/active_scaffold/bridges/dragonfly/lib/dragonfly_bridge_helpers.rb~ +12 -0
  59. data/lib/active_scaffold/bridges/dragonfly/lib/form_ui.rb +27 -0
  60. data/lib/active_scaffold/bridges/dragonfly/lib/form_ui.rb~ +27 -0
  61. data/lib/active_scaffold/bridges/dragonfly/lib/list_ui.rb +16 -0
  62. data/lib/active_scaffold/bridges/dragonfly/lib/list_ui.rb~ +16 -0
  63. data/lib/active_scaffold/bridges/paperclip/bridge.rb +1 -1
  64. data/lib/active_scaffold/bridges/record_select/bridge.rb +5 -0
  65. data/lib/active_scaffold/bridges/record_select/lib/record_select_bridge.rb +87 -0
  66. data/lib/active_scaffold/bridges/record_select/lib/record_select_bridge.rb~ +84 -0
  67. data/lib/active_scaffold/bridges/shared/date_bridge.rb +56 -34
  68. data/lib/active_scaffold/bridges/tiny_mce/lib/tiny_mce_bridge.rb +19 -3
  69. data/lib/active_scaffold/config/base.rb +4 -4
  70. data/lib/active_scaffold/config/core.rb +4 -0
  71. data/lib/active_scaffold/config/create.rb +1 -1
  72. data/lib/active_scaffold/config/field_search.rb +7 -7
  73. data/lib/active_scaffold/config/form.rb +8 -2
  74. data/lib/active_scaffold/config/list.rb +22 -8
  75. data/lib/active_scaffold/config/mark.rb +18 -5
  76. data/lib/active_scaffold/config/nested.rb +3 -3
  77. data/lib/active_scaffold/config/search.rb +1 -1
  78. data/lib/active_scaffold/config/show.rb +1 -1
  79. data/lib/active_scaffold/data_structures/action_columns.rb +10 -6
  80. data/lib/active_scaffold/data_structures/action_link.rb +14 -10
  81. data/lib/active_scaffold/data_structures/action_links.rb +2 -2
  82. data/lib/active_scaffold/data_structures/column.rb +25 -11
  83. data/lib/active_scaffold/data_structures/nested_info.rb +21 -21
  84. data/lib/active_scaffold/data_structures/set.rb +2 -3
  85. data/lib/active_scaffold/data_structures/sorting.rb +8 -8
  86. data/lib/{extensions → active_scaffold/extensions}/action_controller_rendering.rb +3 -1
  87. data/lib/{extensions → active_scaffold/extensions}/action_view_rendering.rb +31 -33
  88. data/lib/{extensions → active_scaffold/extensions}/action_view_resolver.rb +0 -0
  89. data/lib/{extensions → active_scaffold/extensions}/active_association_reflection.rb +0 -0
  90. data/lib/active_scaffold/extensions/active_record_offset.rb +12 -0
  91. data/lib/{extensions → active_scaffold/extensions}/array.rb +0 -0
  92. data/lib/{extensions → active_scaffold/extensions}/localize.rb +1 -1
  93. data/lib/{extensions → active_scaffold/extensions}/name_option_for_datetime.rb +1 -1
  94. data/lib/{extensions → active_scaffold/extensions}/nil_id_in_url_params.rb +0 -0
  95. data/lib/{extensions → active_scaffold/extensions}/paginator_extensions.rb +2 -2
  96. data/lib/{extensions → active_scaffold/extensions}/reverse_associations.rb +1 -1
  97. data/lib/{extensions → active_scaffold/extensions}/routing_mapper.rb +2 -2
  98. data/lib/{extensions → active_scaffold/extensions}/to_label.rb +0 -0
  99. data/lib/{extensions → active_scaffold/extensions}/unsaved_associated.rb +0 -0
  100. data/lib/{extensions → active_scaffold/extensions}/unsaved_record.rb +0 -0
  101. data/lib/active_scaffold/extensions/usa_state.rb +46 -0
  102. data/lib/active_scaffold/finder.rb +30 -19
  103. data/lib/active_scaffold/helpers/controller_helpers.rb +3 -5
  104. data/lib/active_scaffold/helpers/form_column_helpers.rb +19 -45
  105. data/lib/active_scaffold/helpers/human_condition_helpers.rb +1 -1
  106. data/lib/active_scaffold/helpers/id_helpers.rb +2 -2
  107. data/lib/active_scaffold/helpers/list_column_helpers.rb +28 -17
  108. data/lib/active_scaffold/helpers/search_column_helpers.rb +51 -40
  109. data/lib/active_scaffold/helpers/search_column_helpers.rb~ +215 -0
  110. data/lib/active_scaffold/helpers/show_column_helpers.rb +8 -4
  111. data/lib/active_scaffold/helpers/view_helpers.rb +50 -27
  112. data/lib/active_scaffold/locale/de.yml +111 -0
  113. data/lib/active_scaffold/locale/en.yml +115 -0
  114. data/lib/active_scaffold/locale/es.yml +32 -32
  115. data/lib/active_scaffold/locale/fr.yml +118 -0
  116. data/lib/active_scaffold/marked_model.rb +6 -6
  117. data/lib/active_scaffold/version.rb +1 -1
  118. data/lib/active_scaffold_assets.rb +1 -3
  119. data/lib/active_scaffold_env.rb +1 -2
  120. data/lib/generators/active_scaffold/active_scaffold_generator.rb +5 -5
  121. data/lib/generators/active_scaffold_controller/active_scaffold_controller_generator.rb +3 -2
  122. data/lib/generators/active_scaffold_controller/templates/helper.rb +2 -0
  123. data/lib/generators/active_scaffold_setup/active_scaffold_setup_generator.rb +17 -19
  124. data/shoulda_macros/macros.rb +4 -4
  125. data/test/misc/finder_test.rb +2 -2
  126. data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet.css +4 -1
  127. metadata +144 -126
  128. data/.autotest +0 -27
  129. data/.document +0 -5
  130. data/Gemfile +0 -13
  131. data/Gemfile.lock +0 -20
  132. data/Rakefile +0 -53
  133. data/active_scaffold.gemspec +0 -385
  134. data/init.rb +0 -2
  135. data/lib/active_scaffold/helpers/country_helpers.rb +0 -358
  136. data/lib/active_scaffold/locale/de.rb +0 -120
  137. data/lib/active_scaffold/locale/en.rb +0 -119
  138. data/lib/active_scaffold/locale/fr.rb +0 -116
  139. data/lib/extensions/active_record_offset.rb +0 -12
  140. data/lib/extensions/usa_state.rb +0 -50
  141. data/test/mock_app/.gitignore +0 -2
  142. 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
- @parent_record = params[:id].nil? ? active_scaffold_config.model.new : find_if_allowed(params[:id], :update)
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.association.klass.new
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? && active_scaffold_config.update.refresh_list && !render_parent?
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
- # it's an array of ids
114
- if value and not value.empty?
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
- self.bridges.each(&:run) unless self.bridges_run
41
- self.bridges_run = true
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
- require bridge_require
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
@@ -6,4 +6,4 @@ ActiveScaffold::Bridges.bridge "CarrierWave" do
6
6
  require File.join(File.dirname(__FILE__), "lib/carrierwave_bridge")
7
7
  ActiveScaffold::Config::Core.send :include, ActiveScaffold::Bridges::Carrierwave::Lib::CarrierwaveBridge
8
8
  end
9
- end
9
+ 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 "delete_#{field}"
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