active_scaffold 3.0.5 → 3.0.11

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.
Files changed (92) hide show
  1. data/.document +5 -0
  2. data/Gemfile +11 -2
  3. data/Gemfile.lock +20 -0
  4. data/Rakefile +33 -4
  5. data/active_scaffold.gemspec +378 -17
  6. data/frontends/default/images/config.png +0 -0
  7. data/frontends/default/images/gears.png +0 -0
  8. data/frontends/default/javascripts/jquery/active_scaffold.js +34 -33
  9. data/frontends/default/javascripts/jquery/jquery.editinplace.js +21 -4
  10. data/frontends/default/javascripts/prototype/active_scaffold.js +43 -38
  11. data/frontends/default/stylesheets/stylesheet.css +110 -35
  12. data/frontends/default/views/_action_group.html.erb +20 -0
  13. data/frontends/default/views/_base_form.html.erb +7 -3
  14. data/frontends/default/views/_create_form.html.erb +5 -3
  15. data/frontends/default/views/_create_form_on_list.html.erb +2 -1
  16. data/frontends/default/views/_field_search.html.erb +2 -2
  17. data/frontends/default/views/_form.html.erb +2 -2
  18. data/frontends/default/views/_form_messages.html.erb +1 -1
  19. data/frontends/default/views/_horizontal_subform.html.erb +1 -1
  20. data/frontends/default/views/_list_actions.html.erb +6 -14
  21. data/frontends/default/views/_list_header.html.erb +4 -6
  22. data/frontends/default/views/_list_with_header.html.erb +2 -2
  23. data/frontends/default/views/_messages.html.erb +2 -2
  24. data/frontends/default/views/_search.html.erb +2 -2
  25. data/frontends/default/views/_show.html.erb +1 -1
  26. data/frontends/default/views/_update_form.html.erb +2 -1
  27. data/frontends/default/views/_vertical_subform.html.erb +1 -1
  28. data/frontends/default/views/action_confirmation.html.erb +13 -0
  29. data/frontends/default/views/add_existing.js.rjs +1 -1
  30. data/frontends/default/views/destroy.js.rjs +21 -3
  31. data/frontends/default/views/on_action_update.js.rjs +1 -1
  32. data/frontends/default/views/on_create.js.rjs +30 -13
  33. data/frontends/default/views/on_update.js.rjs +19 -6
  34. data/init.rb +6 -0
  35. data/lib/active_scaffold/actions/core.rb +32 -12
  36. data/lib/active_scaffold/actions/create.rb +4 -11
  37. data/lib/active_scaffold/actions/delete.rb +16 -13
  38. data/lib/active_scaffold/actions/list.rb +58 -2
  39. data/lib/active_scaffold/actions/mark.rb +1 -1
  40. data/lib/active_scaffold/actions/nested.rb +24 -15
  41. data/lib/active_scaffold/actions/show.rb +10 -3
  42. data/lib/active_scaffold/actions/update.rb +10 -3
  43. data/lib/{active_record_permissions.rb → active_scaffold/active_record_permissions.rb} +0 -0
  44. data/lib/active_scaffold/bridges/ancestry/lib/ancestry_bridge.rb +9 -8
  45. data/lib/active_scaffold/bridges/bridge.rb +1 -1
  46. data/lib/active_scaffold/bridges/calendar_date_select/lib/as_cds_bridge.rb +8 -4
  47. data/lib/active_scaffold/bridges/carrierwave/bridge.rb +1 -1
  48. data/lib/active_scaffold/bridges/paperclip/bridge.rb +1 -1
  49. data/lib/active_scaffold/bridges/paperclip/lib/list_ui.rb +1 -1
  50. data/lib/active_scaffold/config/base.rb +8 -0
  51. data/lib/active_scaffold/config/core.rb +2 -15
  52. data/lib/active_scaffold/config/create.rb +8 -0
  53. data/lib/active_scaffold/config/delete.rb +10 -1
  54. data/lib/active_scaffold/config/field_search.rb +1 -0
  55. data/lib/active_scaffold/config/form.rb +2 -1
  56. data/lib/active_scaffold/config/nested.rb +3 -2
  57. data/lib/active_scaffold/config/search.rb +1 -0
  58. data/lib/active_scaffold/config/show.rb +1 -0
  59. data/lib/active_scaffold/config/update.rb +8 -0
  60. data/lib/active_scaffold/constraints.rb +9 -4
  61. data/lib/active_scaffold/data_structures/action_columns.rb +1 -1
  62. data/lib/active_scaffold/data_structures/action_link.rb +10 -1
  63. data/lib/active_scaffold/data_structures/action_links.rb +62 -22
  64. data/lib/active_scaffold/data_structures/column.rb +17 -13
  65. data/lib/active_scaffold/data_structures/nested_info.rb +21 -6
  66. data/lib/active_scaffold/finder.rb +2 -1
  67. data/lib/active_scaffold/helpers/association_helpers.rb +2 -2
  68. data/lib/active_scaffold/helpers/controller_helpers.rb +57 -10
  69. data/lib/active_scaffold/helpers/form_column_helpers.rb +12 -8
  70. data/lib/active_scaffold/helpers/id_helpers.rb +5 -9
  71. data/lib/active_scaffold/helpers/list_column_helpers.rb +26 -28
  72. data/lib/active_scaffold/helpers/search_column_helpers.rb +8 -3
  73. data/lib/active_scaffold/helpers/view_helpers.rb +60 -19
  74. data/lib/active_scaffold/locale/de.rb +13 -6
  75. data/lib/active_scaffold/locale/en.rb +2 -1
  76. data/lib/active_scaffold/locale/es.yml +3 -0
  77. data/lib/active_scaffold/locale/fr.rb +5 -2
  78. data/lib/active_scaffold/locale/ru.yml +77 -20
  79. data/lib/active_scaffold/marked_model.rb +5 -5
  80. data/lib/{paginator.rb → active_scaffold/paginator.rb} +0 -0
  81. data/lib/{responds_to_parent.rb → active_scaffold/responds_to_parent.rb} +0 -0
  82. data/lib/active_scaffold/version.rb +9 -0
  83. data/lib/active_scaffold.rb +60 -84
  84. data/lib/active_scaffold_assets.rb +45 -0
  85. data/lib/active_scaffold_env.rb +14 -0
  86. data/lib/active_scaffold_vho.rb +2 -0
  87. data/lib/extensions/active_association_reflection.rb +13 -0
  88. data/lib/extensions/paginator_extensions.rb +1 -1
  89. data/lib/extensions/routing_mapper.rb +1 -1
  90. data/lib/generators/active_scaffold_setup/active_scaffold_setup_generator.rb +12 -4
  91. metadata +85 -68
  92. data/lib/dhtml_confirm.rb +0 -54
@@ -3,13 +3,12 @@ ActiveScaffold::Config::Core.class_eval do
3
3
  initialize_without_ancestry(model_id)
4
4
 
5
5
  return unless self.model.respond_to? :ancestry_column
6
-
7
- col_config = self.columns[self.model.ancestry_column]
8
- unless col_config.nil?
9
- col_config.form_ui = :ancestry
10
- create.columns.exclude :ancestry
11
- list.columns.exclude :ancestry
12
- end
6
+
7
+ self.columns << :parent_id
8
+ self.columns[:parent_id].form_ui = :ancestry
9
+ update.columns.exclude :ancestry
10
+ create.columns.exclude :ancestry, :parent_id
11
+ list.columns.exclude :ancestry, :parent_id
13
12
  end
14
13
 
15
14
  alias_method_chain :initialize, :ancestry
@@ -20,6 +19,8 @@ module ActiveScaffold
20
19
  module FormColumnHelpers
21
20
  def active_scaffold_input_ancestry(column, options)
22
21
  select_options = []
22
+ select_control_options = {:selected => @record.parent_id}
23
+ select_control_options[:include_blank] = as_(:_select_) if @record.parent_id.nil?
23
24
  traverse_ancestry = proc do|key, value|
24
25
  unless key == @record
25
26
  select_options << ["#{'__' * key.depth}#{key.to_label}", key.id]
@@ -27,7 +28,7 @@ module ActiveScaffold
27
28
  end
28
29
  end
29
30
  @record.class.arrange.each(&traverse_ancestry)
30
- select(:record, :ancestry, select_options, { :selected => @record.send(:ancestry) }, options)
31
+ select(:record, :ancestry, select_options, select_control_options, options)
31
32
  end
32
33
  end
33
34
  end
@@ -44,7 +44,7 @@ module ActiveScaffold
44
44
  end
45
45
  end
46
46
 
47
- require "#{File.dirname(__FILE__)}/shared/date_bridge"
47
+ require File.join(File.dirname(__FILE__), 'shared', 'date_bridge.rb')
48
48
  Dir[File.join(File.dirname(__FILE__), "*/bridge.rb")].each{|bridge_require|
49
49
  require bridge_require
50
50
  }
@@ -49,14 +49,18 @@ module ActiveScaffold
49
49
  end
50
50
 
51
51
  module ViewHelpers
52
+ def self.included(base)
53
+ base.alias_method_chain :active_scaffold_stylesheets, :calendar_date_select
54
+ base.alias_method_chain :active_scaffold_javascripts, :calendar_date_select
55
+ end
52
56
  # Provides stylesheets to include with +stylesheet_link_tag+
53
- def active_scaffold_stylesheets(frontend = :default)
54
- super + [calendar_date_select_stylesheets]
57
+ def active_scaffold_stylesheets_with_calendar_date_select(frontend = :default)
58
+ active_scaffold_stylesheets_without_calendar_date_select + [calendar_date_select_stylesheets]
55
59
  end
56
60
 
57
61
  # Provides stylesheets to include with +stylesheet_link_tag+
58
- def active_scaffold_javascripts(frontend = :default)
59
- super + [calendar_date_select_javascripts]
62
+ def active_scaffold_javascripts_with_calendar_date_select(frontend = :default)
63
+ active_scaffold_javascripts_without_calendar_date_select + [calendar_date_select_javascripts]
60
64
  end
61
65
  end
62
66
  end
@@ -2,8 +2,8 @@ ActiveScaffold::Bridges.bridge "CarrierWave" do
2
2
  install do
3
3
  require File.join(File.dirname(__FILE__), "lib/form_ui")
4
4
  require File.join(File.dirname(__FILE__), "lib/list_ui")
5
- require File.join(File.dirname(__FILE__), "lib/carrierwave_bridge")
6
5
  require File.join(File.dirname(__FILE__), "lib/carrierwave_bridge_helpers")
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
9
  end
@@ -5,8 +5,8 @@ ActiveScaffold::Bridges.bridge "Paperclip" do
5
5
  end
6
6
  require File.join(File.dirname(__FILE__), "lib/form_ui")
7
7
  require File.join(File.dirname(__FILE__), "lib/list_ui")
8
- require File.join(File.dirname(__FILE__), "lib/paperclip_bridge")
9
8
  require File.join(File.dirname(__FILE__), "lib/paperclip_bridge_helpers")
9
+ require File.join(File.dirname(__FILE__), "lib/paperclip_bridge")
10
10
  ActiveScaffold::Config::Core.send :include, ActiveScaffold::Bridges::Paperclip::Lib::PaperclipBridge
11
11
  end
12
12
  end
@@ -9,7 +9,7 @@ module ActiveScaffold
9
9
  else
10
10
  paperclip.original_filename
11
11
  end
12
- link_to(content, paperclip.url, :popup => true)
12
+ link_to(content, paperclip.url, {'data-popup' => true, :target => '_blank'})
13
13
  end
14
14
  end
15
15
  end
@@ -17,12 +17,20 @@ module ActiveScaffold::Config
17
17
  end
18
18
  end
19
19
  end
20
+
20
21
  # delegate
21
22
  def crud_type; self.class.crud_type end
22
23
 
23
24
  # the user property gets set to the instantiation of the local UserSettings class during the automatic instantiation of this class.
24
25
  attr_accessor :user
25
26
 
27
+ # define a default action_group for this action
28
+ # e.g. 'members.crud'
29
+ class_inheritable_accessor :action_group
30
+
31
+ # action_group this action should belong to
32
+ attr_accessor :action_group
33
+
26
34
  class UserSettings
27
35
  def initialize(conf, storage, params)
28
36
  # the session hash relevant to this action
@@ -58,6 +58,7 @@ module ActiveScaffold::Config
58
58
 
59
59
  # lets you specify whether add a create link for each sti child
60
60
  cattr_accessor :sti_create_links
61
+ @@sti_create_links = true
61
62
 
62
63
  # instance-level configuration
63
64
  # ----------------------------
@@ -151,21 +152,7 @@ module ActiveScaffold::Config
151
152
  self.columns[column].form_ui ||= :select
152
153
  self.columns[column].options ||= {}
153
154
  self.columns[column].options[:options] = self.sti_children.collect do |model_name|
154
- [model_name.to_s.camelize.constantize.human_name, model_name.to_s.camelize]
155
- end
156
- end
157
- end
158
-
159
- # To be called after include action modules
160
- def _add_sti_create_links
161
- new_action_link = @action_links['new']
162
- unless new_action_link.nil?
163
- @action_links.delete('new')
164
- self.sti_children.each do |child|
165
- new_sti_link = Marshal.load(Marshal.dump(new_action_link)) # deep clone
166
- new_sti_link.label = as_(:create_model, :model => child.to_s.camelize.constantize.human_name)
167
- new_sti_link.parameters = {model.inheritance_column => child}
168
- @action_links.add(new_sti_link)
155
+ [model_name.to_s.camelize.constantize.model_name.human, model_name.to_s.camelize]
169
156
  end
170
157
  end
171
158
  end
@@ -5,6 +5,7 @@ module ActiveScaffold::Config
5
5
  super
6
6
  self.persistent = self.class.persistent
7
7
  self.edit_after_create = self.class.edit_after_create
8
+ self.refresh_list = self.class.refresh_list
8
9
  end
9
10
 
10
11
  # global level configuration
@@ -26,6 +27,10 @@ module ActiveScaffold::Config
26
27
  cattr_accessor :edit_after_create
27
28
  @@edit_after_create = false
28
29
 
30
+ # whether we should refresh list after create or not
31
+ cattr_accessor :refresh_list
32
+ @@refresh_list = false
33
+
29
34
  # instance-level configuration
30
35
  # ----------------------------
31
36
  # the label= method already exists in the Form base class
@@ -39,5 +44,8 @@ module ActiveScaffold::Config
39
44
 
40
45
  # whether the form stays open after a create or not
41
46
  attr_accessor :edit_after_create
47
+
48
+ # whether we should refresh list after create or not
49
+ attr_accessor :refresh_list
42
50
  end
43
51
  end
@@ -7,6 +7,8 @@ module ActiveScaffold::Config
7
7
 
8
8
  # start with the ActionLink defined globally
9
9
  @link = self.class.link.clone
10
+ @action_group = self.class.action_group.clone if self.class.action_group
11
+ self.refresh_list = self.class.refresh_list
10
12
  end
11
13
 
12
14
  # global level configuration
@@ -14,12 +16,19 @@ module ActiveScaffold::Config
14
16
 
15
17
  # the ActionLink for this action
16
18
  cattr_accessor :link
17
- @@link = ActiveScaffold::DataStructures::ActionLink.new('delete', :label => :delete, :type => :member, :confirm => :are_you_sure_to_delete, :crud_type => :delete, :position => false, :security_method => :delete_authorized?)
19
+ @@link = ActiveScaffold::DataStructures::ActionLink.new('destroy', :label => :delete, :type => :member, :confirm => :are_you_sure_to_delete, :method => :delete, :crud_type => :delete, :position => false, :parameters => {:destroy_action => true}, :security_method => :delete_authorized?)
20
+
21
+ # whether we should refresh list after destroy or not
22
+ cattr_accessor :refresh_list
23
+ @@refresh_list = false
18
24
 
19
25
  # instance-level configuration
20
26
  # ----------------------------
21
27
 
22
28
  # the ActionLink for this action
23
29
  attr_accessor :link
30
+
31
+ # whether we should refresh list after destroy or not
32
+ attr_accessor :refresh_list
24
33
  end
25
34
  end
@@ -9,6 +9,7 @@ module ActiveScaffold::Config
9
9
 
10
10
  # start with the ActionLink defined globally
11
11
  @link = self.class.link.clone
12
+ @action_group = self.class.action_group.clone if self.class.action_group
12
13
  end
13
14
 
14
15
 
@@ -4,7 +4,8 @@ module ActiveScaffold::Config
4
4
  @core = core_config
5
5
 
6
6
  # start with the ActionLink defined globally
7
- @link = self.class.link.clone
7
+ @link = self.class.link.clone unless self.class.link.nil?
8
+ @action_group = self.class.action_group.clone if self.class.action_group
8
9
 
9
10
  # no global setting here because multipart should only be set for specific forms
10
11
  @multipart = false
@@ -5,6 +5,7 @@ module ActiveScaffold::Config
5
5
  def initialize(core_config)
6
6
  @core = core_config
7
7
  self.shallow_delete = self.class.shallow_delete
8
+ @action_group = self.class.action_group.clone if self.class.action_group
8
9
  end
9
10
 
10
11
  # global level configuration
@@ -22,7 +23,7 @@ module ActiveScaffold::Config
22
23
  unless column.nil? || column.association.nil?
23
24
  options.reverse_merge! :security_method => :nested_authorized?, :label => column.association.klass.model_name.human({:count => 2, :default => column.association.klass.name.pluralize})
24
25
  action_link = @core.link_for_association(column, options)
25
- @core.action_links.add(action_link) unless action_link.nil?
26
+ @core.action_links.add_to_group(action_link, action_group) unless action_link.nil?
26
27
  else
27
28
 
28
29
  end
@@ -30,7 +31,7 @@ module ActiveScaffold::Config
30
31
 
31
32
  def add_scoped_link(named_scope, options = {})
32
33
  action_link = @core.link_for_association_as_scope(named_scope.to_sym, options)
33
- @core.action_links.add(action_link) unless action_link.nil?
34
+ @core.action_links.add_to_group(action_link, action_group) unless action_link.nil?
34
35
  end
35
36
 
36
37
  # the label for this Nested action. used for the header.
@@ -10,6 +10,7 @@ module ActiveScaffold::Config
10
10
 
11
11
  # start with the ActionLink defined globally
12
12
  @link = self.class.link.clone
13
+ @action_group = self.class.action_group.clone if self.class.action_group
13
14
  end
14
15
 
15
16
 
@@ -6,6 +6,7 @@ module ActiveScaffold::Config
6
6
  @core = core_config
7
7
  # start with the ActionLink defined globally
8
8
  @link = self.class.link.clone
9
+ @action_group = self.class.action_group.clone if self.class.action_group
9
10
  end
10
11
 
11
12
  # global level configuration
@@ -4,6 +4,7 @@ module ActiveScaffold::Config
4
4
  def initialize(*args)
5
5
  super
6
6
  self.nested_links = self.class.nested_links
7
+ self.refresh_list = self.class.refresh_list
7
8
  end
8
9
 
9
10
  # global level configuration
@@ -17,6 +18,10 @@ module ActiveScaffold::Config
17
18
  end
18
19
  @@link = ActiveScaffold::DataStructures::ActionLink.new('edit', :label => :edit, :type => :member, :security_method => :update_authorized?)
19
20
 
21
+ # whether we should refresh list after update or not
22
+ cattr_accessor :refresh_list
23
+ @@refresh_list = false
24
+
20
25
  # instance-level configuration
21
26
  # ----------------------------
22
27
 
@@ -34,5 +39,8 @@ module ActiveScaffold::Config
34
39
  @hide_nested_column.nil? ? true : @hide_nested_column
35
40
  end
36
41
 
42
+ # whether we should refresh list after update or not
43
+ attr_accessor :refresh_list
44
+
37
45
  end
38
46
  end
@@ -120,10 +120,15 @@ module ActiveScaffold
120
120
 
121
121
  condition = constraint_condition_for("#{table}.#{field}", value)
122
122
  if association.options[:polymorphic]
123
- condition = merge_conditions(
124
- condition,
125
- constraint_condition_for("#{table}.#{association.name}_type", params[:parent_model].to_s)
126
- )
123
+ begin
124
+ parent_scaffold = "#{session_info[:parent_scaffold].to_s.camelize}Controller".constantize
125
+ condition = merge_conditions(
126
+ condition,
127
+ constraint_condition_for("#{table}.#{association.name}_type", parent_scaffold.active_scaffold_config.model_id.to_s)
128
+ )
129
+ rescue ActiveScaffold::ControllerNotFound
130
+ nil
131
+ end
127
132
  end
128
133
 
129
134
  condition
@@ -1,6 +1,6 @@
1
1
  module ActiveScaffold::DataStructures
2
2
  # A set of columns. These structures can be nested for organization.
3
- class ActionColumns < Set
3
+ class ActionColumns < ActiveScaffold::DataStructures::Set
4
4
  include ActiveScaffold::Configurable
5
5
 
6
6
  # this lets us refer back to the action responsible for this link, if it exists.
@@ -29,7 +29,16 @@ module ActiveScaffold::DataStructures
29
29
  attr_accessor :action
30
30
 
31
31
  # the controller for this action link. if nil, the current controller should be assumed.
32
- attr_accessor :controller
32
+ attr_writer :controller
33
+
34
+ def controller
35
+ @controller = @controller.call if @controller.is_a?(Proc)
36
+ @controller
37
+ end
38
+
39
+ def static_controller?
40
+ !(@controller.is_a?(Proc) || (@controller == :polymorph))
41
+ end
33
42
 
34
43
  # a hash of request parameters
35
44
  attr_accessor :parameters
@@ -4,6 +4,7 @@ module ActiveScaffold::DataStructures
4
4
 
5
5
  def initialize
6
6
  @set = []
7
+ @name = :root
7
8
  end
8
9
 
9
10
  # adds an ActionLink, creating one from the arguments if need be
@@ -16,7 +17,10 @@ module ActiveScaffold::DataStructures
16
17
  # NOTE: this duplicate check should be done by defining the comparison operator for an Action data structure
17
18
  existing = find_duplicate(link)
18
19
  unless existing
19
- subgroup(link.type, link.type).add_to_set(link)
20
+ # That s for backwards compatibility if we are in root of action_links
21
+ # we have to move actionlink into members or collection subgroup
22
+ group = (name == :root ? subgroup(link.type, link.type) : self)
23
+ group.add_to_set(link)
20
24
  link
21
25
  else
22
26
  existing
@@ -28,41 +32,72 @@ module ActiveScaffold::DataStructures
28
32
  @set << link
29
33
  end
30
34
 
35
+ # adds a link to a specific group
36
+ # groups are represented as a string separated by a dot
37
+ # eg member.crud
38
+ def add_to_group(link, group = nil)
39
+ add_to = root
40
+ add_to = group.split('.').inject(root){|group, group_name| group.send(group_name)} if group
41
+ add_to << link unless link.nil?
42
+ end
43
+
31
44
  # finds an ActionLink by matching the action
32
45
  def [](val)
33
- @set.find do |item|
46
+ links = []
47
+ @set.each do |item|
34
48
  if item.is_a?(ActiveScaffold::DataStructures::ActionLinks)
35
- item[val]
49
+ collected = item[val]
50
+ links << collected unless collected.nil?
36
51
  else
37
- item.action == val.to_s
52
+ links << item if item.action == val.to_s
38
53
  end
39
54
  end
55
+ links.first
40
56
  end
41
57
 
42
58
  def find_duplicate(link)
43
- @set.find do |item|
59
+ links = []
60
+ @set.each do |item|
44
61
  if item.is_a?(ActiveScaffold::DataStructures::ActionLinks)
45
- item.find_duplicate(link)
62
+ collected = item.find_duplicate(link)
63
+ links << collected unless collected.nil?
46
64
  else
47
- item.action == link.action and item.controller == link.controller and item.parameters == link.parameters
65
+ links << item if item.action == link.action and item.static_controller? && item.controller == link.controller and item.parameters == link.parameters
48
66
  end
49
67
  end
68
+ links.first
50
69
  end
51
70
 
52
71
  def delete(val)
53
- @set.delete_if do |item|
54
- if item.is_a?(ActiveScaffold::DataStructures::ActionLinks)
55
- delete(val)
56
- else
57
- item.action == val.to_s
72
+ self.each({:include_set => true}) do |link, set|
73
+ if link.action == val.to_s
74
+ set.delete_if {|item| item.is_a?(ActiveScaffold::DataStructures::ActionLink) && item.action == val.to_s}
58
75
  end
59
76
  end
60
77
  end
61
78
 
79
+ def delete_group(name)
80
+ @set.each do |group|
81
+ if group.name == name
82
+ @set.delete_if {|item| item.is_a?(ActiveScaffold::DataStructures::ActionLinks) && item.name == name}
83
+ else
84
+ group.delete_group(name)
85
+ end if group.is_a?(ActiveScaffold::DataStructures::ActionLinks)
86
+ end
87
+ end
88
+
62
89
  # iterates over the links, possibly by type
63
- def each(type = nil)
90
+ def each(options = {}, &block)
64
91
  @set.each {|item|
65
- yield item
92
+ if item.is_a?(ActiveScaffold::DataStructures::ActionLinks)
93
+ item.each(options, &block)
94
+ else
95
+ if options[:include_set]
96
+ yield item, @set
97
+ else
98
+ yield item
99
+ end
100
+ end
66
101
  }
67
102
  end
68
103
 
@@ -74,19 +109,24 @@ module ActiveScaffold::DataStructures
74
109
 
75
110
  def traverse(controller, options = {}, &block)
76
111
  traverse_method = options.delete(:reverse).nil? ? :each : :reverse_each
112
+ options[:level] ||= -1
113
+ options[:level] += 1
114
+ first_action = true
77
115
  @set.send(traverse_method) do |link|
78
116
  if link.is_a?(ActiveScaffold::DataStructures::ActionLinks)
79
- # add top node only if there is anything in the list
80
- #yield({:kind => :node, :level => 1, :last => false, :link => link})
81
- yield(link, nil, {:node => :start_traversing})
82
- link.traverse(controller,options, &block)
83
- yield(link, nil, {:node => :finished_traversing})
84
- #yield({:kind => :completed_group, :level => 1, :last => false, :link => link})
85
- elsif controller.nil? || !skip_action_link(controller, link, options[:record])
117
+ unless link.empty?
118
+ yield(link, nil, {:node => :start_traversing, :first_action => first_action, :level => options[:level]})
119
+ link.traverse(controller,options, &block)
120
+ yield(link, nil, {:node => :finished_traversing, :first_action => first_action, :level => options[:level]})
121
+ first_action = false
122
+ end
123
+ elsif controller.nil? || !skip_action_link(controller, link, *(Array(options[:for])))
86
124
  authorized = options[:for].nil? ? true : options[:for].authorized_for?(:crud_type => link.crud_type, :action => link.action)
87
- yield(self, link, {:authorized => authorized})
125
+ yield(self, link, {:authorized => authorized, :first_action => first_action, :level => options[:level]})
126
+ first_action = false
88
127
  end
89
128
  end
129
+ options[:level] -= 1
90
130
  end
91
131
 
92
132
  def collect
@@ -114,22 +114,14 @@ module ActiveScaffold::DataStructures
114
114
  @options ||= {}
115
115
  end
116
116
 
117
- # associate an action_link with this column
118
- attr_reader :link
119
-
120
- # set an action_link to nested list or inline form in this column
121
- def autolink?
122
- @autolink
123
- end
124
-
125
- # this should not only delete any existing link but also prevent column links from being automatically added by later routines
126
- def clear_link
127
- @link = nil
128
- @autolink = false
117
+ def link
118
+ @link = @link.call(self) if @link.is_a? Proc
119
+ @link
129
120
  end
130
121
 
122
+ # associate an action_link with this column
131
123
  def set_link(action, options = {})
132
- if action.is_a? ActiveScaffold::DataStructures::ActionLink
124
+ if action.is_a?(ActiveScaffold::DataStructures::ActionLink) || (action.is_a? Proc)
133
125
  @link = action
134
126
  else
135
127
  options[:label] ||= self.label
@@ -139,6 +131,17 @@ module ActiveScaffold::DataStructures
139
131
  end
140
132
  end
141
133
 
134
+ # set an action_link to nested list or inline form in this column
135
+ def autolink?
136
+ @autolink
137
+ end
138
+
139
+ # this should not only delete any existing link but also prevent column links from being automatically added by later routines
140
+ def clear_link
141
+ @link = nil
142
+ @autolink = false
143
+ end
144
+
142
145
  # define a calculation for the column. anything that ActiveRecord::Calculations::ClassMethods#calculate accepts will do.
143
146
  attr_accessor :calculate
144
147
 
@@ -267,6 +270,7 @@ module ActiveScaffold::DataStructures
267
270
  @actions_for_association_links = self.class.actions_for_association_links.clone if @association
268
271
  @options = {:format => :i18n_number} if @column.try(:number?)
269
272
  @form_ui = :checkbox if @column and @column.type == :boolean
273
+ @form_ui = :textarea if @column and @column.type == :text
270
274
  @allow_add_existing = true
271
275
  @form_ui = self.class.association_form_ui if @association && self.class.association_form_ui
272
276
 
@@ -5,20 +5,27 @@ module ActiveScaffold::DataStructures
5
5
  nil
6
6
  else
7
7
  session_info = session_storage[:nested].clone
8
- session_info[:association] = session_info[:parent_model].reflect_on_association(session_info[:name])
9
- unless session_info[:association].nil?
10
- ActiveScaffold::DataStructures::NestedInfoAssociation.new(model, session_info)
11
- else
12
- ActiveScaffold::DataStructures::NestedInfoScope.new(model, session_info)
8
+ begin
9
+ session_info[:parent_scaffold] = "#{session_info[:parent_scaffold].to_s.camelize}Controller".constantize
10
+ session_info[:parent_model] = session_info[:parent_scaffold].active_scaffold_config.model
11
+ session_info[:association] = session_info[:parent_model].reflect_on_association(session_info[:name])
12
+ unless session_info[:association].nil?
13
+ ActiveScaffold::DataStructures::NestedInfoAssociation.new(model, session_info)
14
+ else
15
+ ActiveScaffold::DataStructures::NestedInfoScope.new(model, session_info)
16
+ end
17
+ rescue ActiveScaffold::ControllerNotFound
18
+ nil
13
19
  end
14
20
  end
15
21
  end
16
22
 
17
- attr_accessor :association, :child_association, :parent_model, :parent_id, :constrained_fields, :scope
23
+ attr_accessor :association, :child_association, :parent_model, :parent_scaffold, :parent_id, :constrained_fields, :scope
18
24
 
19
25
  def initialize(model, session_info)
20
26
  @parent_model = session_info[:parent_model]
21
27
  @parent_id = session_info[:parent_id]
28
+ @parent_scaffold = session_info[:parent_scaffold]
22
29
  end
23
30
 
24
31
  def new_instance?
@@ -39,6 +46,10 @@ module ActiveScaffold::DataStructures
39
46
  false
40
47
  end
41
48
 
49
+ def has_one?
50
+ false
51
+ end
52
+
42
53
  def readonly?
43
54
  false
44
55
  end
@@ -63,6 +74,10 @@ module ActiveScaffold::DataStructures
63
74
  association.belongs_to?
64
75
  end
65
76
 
77
+ def has_one?
78
+ association.macro == :has_one
79
+ end
80
+
66
81
  def readonly?
67
82
  if association.options.has_key? :readonly
68
83
  association.options[:readonly]
@@ -125,7 +125,7 @@ module ActiveScaffold
125
125
  native = '.'
126
126
  delimiter = I18n.t('number.format.delimiter')
127
127
  separator = I18n.t('number.format.separator')
128
-
128
+ return value if value.blank? || !value.is_a?(String)
129
129
  unless delimiter == native && !value.include?(separator) && value !~ /\.\d{3}$/
130
130
  value.gsub(/[^0-9\-#{I18n.t('number.format.separator')}]/, '').gsub(I18n.t('number.format.separator'), native)
131
131
  else
@@ -292,6 +292,7 @@ module ActiveScaffold
292
292
  def append_to_query(query, options)
293
293
  options.assert_valid_keys :where, :select, :group, :order, :limit, :offset, :joins, :includes, :lock, :readonly, :from
294
294
  options.reject{|k, v| v.blank?}.inject(query) do |query, (k, v)|
295
+ query = query.except(:order) if k.to_sym == :order
295
296
  query.send((k.to_sym), v)
296
297
  end
297
298
  end
@@ -3,11 +3,11 @@ module ActiveScaffold
3
3
  module AssociationHelpers
4
4
  # Provides a way to honor the :conditions on an association while searching the association's klass
5
5
  def association_options_find(association, conditions = nil)
6
- association.klass.where(controller.send(:merge_conditions, conditions, association.options[:conditions])).all
6
+ association.klass.where(conditions).where(association.options[:conditions]).all
7
7
  end
8
8
 
9
9
  def association_options_count(association, conditions = nil)
10
- association.klass.where(controller.send(:merge_conditions, conditions, association.options[:conditions])).count
10
+ association.klass.where(conditions).where(association.options[:conditions]).count
11
11
  end
12
12
 
13
13
  # returns options for the given association as a collection of [id, label] pairs intended for the +options_for_select+ helper.