active_scaffold_vho 3.0.31 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. data/Gemfile +9 -1
  2. data/Gemfile.lock +8 -79
  3. data/Rakefile +17 -20
  4. data/active_scaffold_vho.gemspec +374 -15
  5. data/{frontends/default → app/assets}/images/add.gif +0 -0
  6. data/{frontends/default → app/assets}/images/arrow_down.gif +0 -0
  7. data/{frontends/default → app/assets}/images/arrow_up.gif +0 -0
  8. data/{frontends/default → app/assets}/images/close.gif +0 -0
  9. data/{frontends/default → app/assets}/images/close_touch.png +0 -0
  10. data/{frontends/default → app/assets}/images/config.png +0 -0
  11. data/{frontends/default → app/assets}/images/cross.png +0 -0
  12. data/{frontends/default → app/assets}/images/gears.png +0 -0
  13. data/{frontends/default → app/assets}/images/indicator-small.gif +0 -0
  14. data/{frontends/default → app/assets}/images/indicator.gif +0 -0
  15. data/{frontends/default → app/assets}/images/magnifier.png +0 -0
  16. data/app/assets/javascripts/active_scaffold.js.erb +12 -0
  17. data/{frontends/default → app/assets}/javascripts/jquery/active_scaffold.js +73 -245
  18. data/app/assets/javascripts/jquery/date_picker_bridge.js.erb +24 -0
  19. data/app/assets/javascripts/jquery/jquery-ui-timepicker-addon.js +1060 -0
  20. data/{frontends/default → app/assets}/javascripts/jquery/jquery.editinplace.js +1 -1
  21. data/{lib/active_scaffold/bridges/tiny_mce/public → app/assets}/javascripts/jquery/tiny_mce_bridge.js +4 -3
  22. data/{frontends/default → app/assets}/javascripts/prototype/active_scaffold.js +36 -122
  23. data/{frontends/default → app/assets}/javascripts/prototype/dhtml_history.js +0 -0
  24. data/{frontends/default → app/assets}/javascripts/prototype/form_enhancements.js +0 -0
  25. data/{frontends/default → app/assets}/javascripts/prototype/rico_corner.js +0 -0
  26. data/{frontends/default/stylesheets/stylesheet-ie.css → app/assets/stylesheets/active_scaffold-ie.css} +0 -0
  27. data/{frontends/default/stylesheets/stylesheet.css → app/assets/stylesheets/active_scaffold.css.erb} +24 -22
  28. data/app/assets/stylesheets/jquery-ui-timepicker-addon.css +6 -0
  29. data/frontends/default/views/_action_group.html.erb +1 -1
  30. data/frontends/default/views/_base_form.html.erb +1 -1
  31. data/frontends/default/views/_form_association_footer.html.erb +11 -7
  32. data/frontends/default/views/_horizontal_subform_record.html.erb +5 -9
  33. data/frontends/default/views/_list.html.erb +1 -2
  34. data/frontends/default/views/_list_inline_adapter.html.erb +10 -0
  35. data/frontends/default/views/_list_messages.html.erb +2 -2
  36. data/frontends/default/views/_list_pagination.html.erb +6 -3
  37. data/frontends/default/views/_list_pagination_links.html.erb +9 -0
  38. data/frontends/default/views/_list_record.html.erb +2 -1
  39. data/frontends/default/views/_list_record_columns.html.erb +2 -1
  40. data/frontends/default/views/_list_with_header.html.erb +1 -1
  41. data/frontends/default/views/_messages.html.erb +0 -1
  42. data/frontends/default/views/_render_field.js.erb +13 -0
  43. data/frontends/default/views/_vertical_subform_record.html.erb +5 -9
  44. data/frontends/default/views/add_existing.js.erb +20 -0
  45. data/frontends/default/views/destroy.js.erb +24 -0
  46. data/frontends/default/views/{edit_associated.js.rjs → edit_associated.js.erb} +3 -2
  47. data/frontends/default/views/form_messages.js.erb +1 -0
  48. data/frontends/default/views/list.js.erb +1 -0
  49. data/frontends/default/views/on_action_update.js.erb +13 -0
  50. data/frontends/default/views/on_create.js.erb +45 -0
  51. data/frontends/default/views/on_mark_all.js.erb +12 -0
  52. data/frontends/default/views/on_update.js.erb +31 -0
  53. data/frontends/default/views/update_column.js.erb +16 -0
  54. data/frontends/default/views/update_row.js.erb +1 -0
  55. data/init.rb +1 -7
  56. data/lib/active_scaffold/actions/delete.rb +3 -5
  57. data/lib/active_scaffold/actions/field_search.rb +2 -6
  58. data/lib/active_scaffold/actions/list.rb +16 -14
  59. data/lib/active_scaffold/actions/search.rb +3 -3
  60. data/lib/active_scaffold/active_record_permissions.rb +2 -25
  61. data/lib/active_scaffold/attribute_params.rb +21 -44
  62. data/lib/active_scaffold/bridges/calendar_date_select/bridge.rb +1 -1
  63. data/lib/active_scaffold/bridges/date_picker/bridge.rb +2 -16
  64. data/lib/active_scaffold/bridges/date_picker/lib/datepicker_bridge.rb +86 -56
  65. data/lib/active_scaffold/bridges/file_column/bridge.rb +1 -1
  66. data/lib/active_scaffold/bridges/file_column/lib/as_file_column_bridge.rb +1 -1
  67. data/lib/active_scaffold/bridges/file_column/lib/file_column_helpers.rb +1 -1
  68. data/lib/active_scaffold/bridges/paperclip/bridge.rb +1 -1
  69. data/lib/active_scaffold/bridges/paperclip/lib/paperclip_bridge_helpers.rb +2 -2
  70. data/lib/active_scaffold/bridges/shared/date_bridge.rb +3 -3
  71. data/lib/active_scaffold/bridges/tiny_mce/bridge.rb +0 -12
  72. data/lib/active_scaffold/bridges/validation_reflection/lib/validation_reflection_bridge.rb +1 -1
  73. data/lib/active_scaffold/config/base.rb +1 -1
  74. data/lib/active_scaffold/config/core.rb +1 -8
  75. data/lib/active_scaffold/config/delete.rb +1 -1
  76. data/lib/active_scaffold/config/field_search.rb +1 -22
  77. data/lib/active_scaffold/config/list.rb +10 -18
  78. data/lib/active_scaffold/data_structures/action_link.rb +9 -0
  79. data/lib/active_scaffold/data_structures/action_links.rb +1 -1
  80. data/lib/active_scaffold/data_structures/column.rb +4 -30
  81. data/lib/active_scaffold/data_structures/nested_info.rb +3 -3
  82. data/lib/active_scaffold/data_structures/sorting.rb +1 -1
  83. data/lib/active_scaffold/engine.rb +8 -0
  84. data/lib/active_scaffold/extensions/action_controller_rendering.rb +22 -0
  85. data/lib/active_scaffold/extensions/action_view_rendering.rb +79 -59
  86. data/lib/active_scaffold/extensions/action_view_resolver.rb +4 -2
  87. data/lib/active_scaffold/extensions/active_association_reflection.rb +3 -3
  88. data/lib/active_scaffold/extensions/reverse_associations.rb +3 -3
  89. data/lib/active_scaffold/finder.rb +27 -39
  90. data/lib/active_scaffold/helpers/association_helpers.rb +3 -3
  91. data/lib/active_scaffold/helpers/form_column_helpers.rb +3 -3
  92. data/lib/active_scaffold/helpers/human_condition_helpers.rb +2 -4
  93. data/lib/active_scaffold/helpers/list_column_helpers.rb +16 -22
  94. data/lib/active_scaffold/helpers/search_column_helpers.rb +1 -1
  95. data/lib/active_scaffold/helpers/view_helpers.rb +35 -13
  96. data/lib/active_scaffold/locale/de.rb +120 -0
  97. data/lib/active_scaffold/locale/en.rb +119 -0
  98. data/lib/active_scaffold/version.rb +2 -2
  99. data/lib/active_scaffold.rb +12 -27
  100. data/lib/active_scaffold_env.rb +3 -3
  101. data/test/mock_app/public/stylesheets/active_scaffold/default/stylesheet.css +1 -1
  102. metadata +84 -86
  103. data/.gitignore +0 -42
  104. data/frontends/default/views/_render_field.js.rjs +0 -10
  105. data/frontends/default/views/add_existing.js.rjs +0 -17
  106. data/frontends/default/views/destroy.js.rjs +0 -23
  107. data/frontends/default/views/form_messages.js.rjs +0 -1
  108. data/frontends/default/views/list.js.rjs +0 -1
  109. data/frontends/default/views/on_action_update.js.rjs +0 -10
  110. data/frontends/default/views/on_create.js.rjs +0 -41
  111. data/frontends/default/views/on_mark_all.js.rjs +0 -12
  112. data/frontends/default/views/on_update.js.rjs +0 -28
  113. data/frontends/default/views/update_column.js.rjs +0 -13
  114. data/frontends/default/views/update_row.js.rjs +0 -1
  115. data/lib/active_scaffold/bridges/date_picker/public/javascripts/date_picker_bridge.js +0 -36
  116. data/lib/active_scaffold/bridges/tiny_mce/public/javascripts/prototype/tiny_mce_bridge.js +0 -21
  117. data/lib/active_scaffold/locale/de.yml +0 -120
  118. data/lib/active_scaffold/locale/en.yml +0 -115
  119. data/lib/active_scaffold_assets.rb +0 -45
@@ -1,24 +1,28 @@
1
1
  module ActionView
2
2
  class LookupContext
3
3
  module ViewPaths
4
- def find_all_templates(name, prefix = nil, partial = false)
5
- templates = []
6
- @view_paths.each do |resolver|
7
- template = resolver.find_all(*args_for_lookup(name, prefix, partial)).first
8
- templates << template unless template.nil?
9
- end
10
- templates
4
+
5
+ def find_all_templates(name, partial = false, locals = {})
6
+ prefixes.collect do |prefix|
7
+ @view_paths.collect do |resolver|
8
+ temp_args = *args_for_lookup(name, [prefix], partial, locals)
9
+ temp_args[1] = temp_args[1][0]
10
+ resolver.find_all(*temp_args)
11
+ end
12
+ end.flatten!
11
13
  end
12
14
  end
13
15
  end
14
16
  end
15
17
 
16
18
  # wrap the action rendering for ActiveScaffold views
17
- module ActionView::Rendering #:nodoc:
19
+ module ActionView #:nodoc:
20
+ class Renderer
21
+ #
18
22
  # Adds two rendering options.
19
23
  #
20
24
  # ==render :super
21
- # ==render :super, :locals =>{:headline => 'formheadline'}
25
+ # ==render :partial => :super, :locals =>{:headline => 'formheadline'}
22
26
  #
23
27
  # This syntax skips all template overrides and goes directly to the provided ActiveScaffold templates.
24
28
  # Useful if you want to wrap an existing template. Just call super!
@@ -37,83 +41,99 @@ module ActionView::Rendering #:nodoc:
37
41
  #
38
42
  # Defining options[:label] lets you completely customize the list title for the embedded scaffold.
39
43
  #
40
- def render_with_active_scaffold(*args, &block)
41
- options = args.first
42
- if options == :super
44
+ def render_with_active_scaffold(context, options, &block)
45
+ if options && options[:partial] == :super
46
+ render_as_super_view(context, options, &block)
47
+ elsif context.is_a?(Hash) and context[:active_scaffold]
48
+ render_as_embedded_view(context, options, &block)
49
+ else
50
+ render_as_view(context, options, &block)
51
+ end
52
+ end
53
+ alias_method_chain :render, :active_scaffold
54
+
55
+ def render_partial_with_active_scaffold(context, options, &block) #:nodoc:
56
+ if block_given?
57
+ render(context, options, block)
58
+ else
59
+ render(context, options)
60
+ end
61
+ end
62
+ alias_method_chain :render_partial, :active_scaffold
63
+
64
+ def render_template_with_active_scaffold(context, options) #:nodoc:
65
+ render(context, options)
66
+ end
67
+ alias_method_chain :render_template, :active_scaffold
68
+
69
+
70
+ def render_as_super_view(context, options, &block)
43
71
  last_view = @view_stack.last
44
- options = args[1] || {}
45
72
  options[:locals] ||= {}
46
73
  options[:locals].reverse_merge!(last_view[:locals] || {})
47
74
  if last_view[:templates].nil?
48
- last_view[:templates] = lookup_context.find_all_templates(last_view[:view], controller_path, !last_view[:is_template])
75
+ last_view[:templates] = lookup_context.find_all_templates(last_view[:view], !last_view[:is_template], options[:locals].keys)
49
76
  last_view[:templates].shift
50
77
  end
51
78
  options[:template] = last_view[:templates].shift
52
79
  @view_stack << last_view
53
- result = render_without_active_scaffold options
80
+ options.delete(:partial) if options[:partial] == :super
81
+ result = if options.key?(:partial)
82
+ render_partial_without_active_scaffold(last_view[:context], options)
83
+ else
84
+ render_template_without_active_scaffold(last_view[:context], options)
85
+ end
54
86
  @view_stack.pop
55
87
  result
56
- elsif options.is_a?(Hash) && options[:active_scaffold]
57
- require 'digest/md5'
88
+ end
58
89
 
90
+ def render_as_embedded_view(context, options, &block)
91
+ require 'digest/md5'
59
92
  remote_controller = options[:active_scaffold]
60
93
  constraints = options[:constraints]
61
94
  conditions = options[:conditions]
62
95
  eid = Digest::MD5.hexdigest(params[:controller] + remote_controller.to_s + constraints.to_s + conditions.to_s)
63
- session["as:#{eid}"] = {:constraints => constraints, :conditions => conditions, :list => {:label => options[:label]}}
96
+ session["as:#{eid}"] = {:constraints => constraints, :conditions => conditions, :list => {:label => args.first[:label]}}
64
97
  options[:params] ||= {}
65
98
  options[:params].merge! :eid => eid, :embedded => true
66
-
99
+
67
100
  id = "as_#{eid}-content"
68
101
  url_options = {:controller => remote_controller.to_s, :action => 'index'}.merge(options[:params])
69
-
70
- unless controller.respond_to?(:render_component_into_view)
102
+
103
+ if controller.respond_to?(:render_component_into_view)
71
104
  controller.send(:render_component_into_view, url_options)
72
105
  else
73
- url_options.delete(:embedded)
74
- content_tag(:div, {:id => id, :class => 'active-scaffold-component'}) do
106
+ content_tag(:div, {:id => id}) do
75
107
  url = url_for(url_options)
76
- link_to(remote_controller.to_s, url, {:remote => true, :class => 'as_link_to_component'})
77
- end
78
- end
79
-
80
- else
81
- if options.is_a?(Hash)
82
- current_view = {:view => options[:partial], :is_template => false} if options[:partial]
83
- current_view = {:view => options[:template], :is_template => !!options[:template]} if current_view.nil? && options[:template]
84
- current_view[:locals] = options[:locals] if !current_view.nil? && options[:locals]
85
- if current_view.present?
86
- @view_stack ||= []
87
- @view_stack << current_view
108
+ link_to(remote_controller.to_s, url, {:remote => true, :id => id}) <<
109
+ if ActiveScaffold.js_framework == :prototype
110
+ javascript_tag("new Ajax.Updater('#{id}', '#{url}', {method: 'get', evalScripts: true});")
111
+ elsif ActiveScaffold.js_framework == :jquery
112
+ javascript_tag("$('##{id}').load('#{url}');")
113
+ end
88
114
  end
89
115
  end
90
- result = render_without_active_scaffold(*args, &block)
91
- @view_stack.pop if current_view.present?
92
- result
93
116
  end
94
- end
95
- alias_method_chain :render, :active_scaffold
96
-
97
117
 
98
- def partial_pieces(partial_path)
99
- if partial_path.include?('/')
100
- return File.dirname(partial_path), File.basename(partial_path)
101
- else
102
- return controller.class.controller_path, partial_path
118
+ def render_as_view(context, options, &block)
119
+ if options.is_a?(Hash)
120
+ current_view = {:view => options[:partial], :is_template => false} if options[:partial]
121
+ current_view = {:view => options[:template], :is_template => !!options[:template]} if current_view.nil? && options[:template]
122
+ if current_view.present?
123
+ current_view[:locals] = options[:locals] if options[:locals]
124
+ current_view[:context] = context
125
+ @view_stack ||= []
126
+ @view_stack << current_view
127
+ end
128
+ end
129
+ result = if options.key?(:partial)
130
+ render_partial_without_active_scaffold(context, options, &block)
131
+ else
132
+ render_template_without_active_scaffold(context, options, &block)
133
+ end
134
+ result
103
135
  end
104
136
  end
137
+
105
138
 
106
- # This is the template finder logic, keep it updated with however we find stuff in rails
107
- # currently this very similar to the logic in ActionBase::Base.render for options file
108
- # TODO: Work with rails core team to find a better way to check for this.
109
- def template_exists?(template_name, lookup_overrides = false)
110
- begin
111
- method = 'find_template'
112
- method << '_without_active_scaffold' unless lookup_overrides
113
- self.view_paths.send(method, template_name, @template_format)
114
- return true
115
- rescue ActionView::MissingTemplate => e
116
- return false
117
- end
118
- end
119
139
  end
@@ -1,7 +1,9 @@
1
1
  module ActionView
2
2
  class ActiveScaffoldResolver < FileSystemResolver
3
- def build_path(name, prefix, partial, details)
4
- super(name, '', partial, details)
3
+ # standard resolvers have a base path to views and append a controller subdirectory
4
+ # activescaffolds view path do not have a subdir, so just remove the prefix
5
+ def find_templates(name, prefix, partial, details)
6
+ super(name,'',partial, details)
5
7
  end
6
8
  end
7
9
  end
@@ -1,13 +1,13 @@
1
1
  # Bugfix: building an sti model from an association fails
2
2
  # https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/6306-collection-associations-build-method-not-supported-for-sti
3
3
  ActiveRecord::Reflection::AssociationReflection.class_eval do
4
- def build_association(*opts)
4
+ def build_association(*opts, &block)
5
5
  col = klass.inheritance_column.to_sym
6
6
  if !col.nil? && opts.first.is_a?(Hash) && (opts.first.symbolize_keys[col])
7
7
  sti_model = opts.first.delete(col)
8
- sti_model.to_s.camelize.constantize.new(*opts)
8
+ sti_model.to_s.camelize.constantize.new(*opts, &block)
9
9
  else
10
- klass.new(*opts)
10
+ klass.new(*opts, &block)
11
11
  end
12
12
  end
13
13
  end
@@ -20,7 +20,7 @@ module ActiveRecord
20
20
  def reverse_matches_for(klass)
21
21
  reverse_matches = []
22
22
 
23
- # stage 1 filter: collect associations that point back to this model and use the same primary_key_name
23
+ # stage 1 filter: collect associations that point back to this model and use the same foreign_key
24
24
  klass.reflect_on_all_associations.each do |assoc|
25
25
  if self.options[:through]
26
26
  # only iterate has_many :through associations
@@ -40,9 +40,9 @@ module ActiveRecord
40
40
  when 1
41
41
  next
42
42
 
43
- # otherwise, match them based on the primary_key_name
43
+ # otherwise, match them based on the foreign_key
44
44
  when 0
45
- next unless assoc.primary_key_name.to_sym == self.primary_key_name.to_sym
45
+ next unless assoc.foreign_key.to_sym == self.foreign_key.to_sym
46
46
  end
47
47
  end
48
48
 
@@ -83,28 +83,21 @@ module ActiveScaffold
83
83
  end
84
84
  end
85
85
 
86
-
87
86
  def condition_for_range(column, value, like_pattern = nil)
88
87
  if !value.is_a?(Hash)
89
88
  if column.column.nil? || column.column.text?
90
- ["#{column.search_sql} #{ActiveScaffold::Finder.like_operator} ?", like_pattern.sub('?', column.stripped_value(value))]
89
+ ["#{column.search_sql} #{ActiveScaffold::Finder.like_operator} ?", like_pattern.sub('?', value)]
91
90
  else
92
91
  ["#{column.search_sql} = ?", column.column.type_cast(value)]
93
92
  end
94
93
  elsif value[:from].blank?
95
94
  nil
96
95
  elsif ActiveScaffold::Finder::StringComparators.values.include?(value[:opt])
97
- if(active_scaffold_config.field_search.or_columns.include? column.name)
98
- search_values = column.stripped_value(value[:from]).split(active_scaffold_config.field_search.or_delimiter).compact
99
- sql_prepared_statement = search_values.collect {|search_value| "#{column.search_sql} #{ActiveScaffold::Finder.like_operator} ?"}.join(' OR ')
100
- [sql_prepared_statement] + search_values.collect{|search_value| value[:opt].sub('?', column.stripped_value(search_value))}
101
- else
102
- ["#{column.search_sql} #{ActiveScaffold::Finder.like_operator} ?", value[:opt].sub('?', column.stripped_value(value[:from]))]
103
- end
96
+ ["#{column.search_sql} #{ActiveScaffold::Finder.like_operator} ?", value[:opt].sub('?', value[:from])]
104
97
  elsif value[:opt] == 'BETWEEN'
105
- ["#{column.search_sql} BETWEEN ? AND ?", column.stripped_value(value[:from]), column.stripped_value(value[:to])]
98
+ ["#{column.search_sql} BETWEEN ? AND ?", value[:from], value[:to]]
106
99
  elsif ActiveScaffold::Finder::NumericComparators.include?(value[:opt])
107
- ["#{column.search_sql} #{value[:opt]} ?", column.stripped_value(value[:from])]
100
+ ["#{column.search_sql} #{value[:opt]} ?", value[:from]]
108
101
  else
109
102
  nil
110
103
  end
@@ -250,7 +243,7 @@ module ActiveScaffold
250
243
  return record
251
244
  end
252
245
 
253
- # returns a records relation for the current page
246
+ # returns a Paginator::Page (not from ActiveRecord::Paginator) for the given parameters
254
247
  # options may include:
255
248
  # * :sorting - a Sorting DataStructure (basically an array of hashes of field => direction, e.g. [{:field1 => 'asc'}, {:field2 => 'desc'}]). please note that multi-column sorting has some limitations: if any column in a multi-field sort uses method-based sorting, it will be ignored. method sorting only works for single-column sorting.
256
249
  # * :per_page
@@ -263,46 +256,41 @@ module ActiveScaffold
263
256
  full_includes = (active_scaffold_includes.blank? ? nil : active_scaffold_includes)
264
257
  options[:per_page] ||= 999999999
265
258
  options[:page] ||= 1
266
- #TODO not supported by kaminari
267
259
  options[:count_includes] ||= full_includes unless search_conditions.nil?
268
260
 
269
- #active_scaffold_config.model.skip_total_count = true if options[:pagination] == :infinite
270
-
271
261
  klass = beginning_of_chain
272
- klass = klass.where("") if klass.is_a?(Array)
273
-
262
+
274
263
  # create a general-use options array that's compatible with Rails finders
275
264
  finder_options = { :order => options[:sorting].try(:clause),
276
265
  :where => search_conditions,
277
266
  :joins => joins_for_finder,
278
- :includes => add_association_to_includes_for_sorting(options[:sorting], full_includes)}
279
-
280
-
267
+ :includes => options[:count_includes]}
268
+
281
269
  finder_options.merge! custom_finder_options
282
270
 
271
+ # NOTE: we must use :include in the count query, because some conditions may reference other tables
272
+ count_query = append_to_query(klass, finder_options.reject{|k, v| [:select, :order].include?(k)})
273
+ count = count_query.count unless options[:pagination] == :infinite
274
+
275
+ # Converts count to an integer if ActiveRecord returned an OrderedHash
276
+ # that happens when finder_options contains a :group key
277
+ count = count.length if count.is_a? ActiveSupport::OrderedHash
278
+ finder_options.merge! :includes => full_includes
279
+
283
280
  # we build the paginator differently for method- and sql-based sorting
284
- records = if options[:sorting] && options[:sorting].sorts_by_method?
285
- Kaminari.paginate_array(sort_collection_by_column(append_to_query(klass, finder_options).all, *options[:sorting].first))
281
+ if options[:sorting] and options[:sorting].sorts_by_method?
282
+ pager = ::Paginator.new(count, options[:per_page]) do |offset, per_page|
283
+ sorted_collection = sort_collection_by_column(append_to_query(klass, finder_options).all, *options[:sorting].first)
284
+ sorted_collection = sorted_collection.slice(offset, per_page) if options[:pagination]
285
+ sorted_collection
286
+ end
286
287
  else
287
- append_to_query(klass, finder_options)
288
- end
289
- records = records.page(options[:page]).per(options[:per_page]) if options[:pagination]
290
- records
291
- end
292
-
293
- # if someone excludes association from includes in configuration
294
- # and sorts by that that column... database will not be happy about it :-)
295
- # just a safety check to prevent many many database queries
296
- def add_association_to_includes_for_sorting(sorting, full_includes)
297
- if sorting && sorting.sorts_by_method?
298
- sorting_column = sorting.first.first
299
- #wants to sort by assocation which is not included bad performance...
300
- if sorting_column.association && !sorting_column.polymorphic_association? &&
301
- sorting_column.includes.empty? && !full_includes.include?(sorting_column.association.name)
302
- full_includes << sorting_column.association.name
288
+ pager = ::Paginator.new(count, options[:per_page]) do |offset, per_page|
289
+ finder_options.merge!(:offset => offset, :limit => per_page) if options[:pagination]
290
+ append_to_query(klass, finder_options).all
303
291
  end
304
292
  end
305
- full_includes
293
+ pager.page(options[:page])
306
294
  end
307
295
 
308
296
  def append_to_query(query, options)
@@ -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(conditions).where(association.options[:conditions])
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_options_find(association, 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.
@@ -29,7 +29,7 @@ module ActiveScaffold
29
29
  case association.macro
30
30
  when :has_one, :has_many
31
31
  # Find only orphaned objects
32
- "#{association.primary_key_name} IS NULL"
32
+ "#{association.foreign_key} IS NULL"
33
33
  when :belongs_to, :has_and_belongs_to_many
34
34
  # Find all
35
35
  nil
@@ -190,7 +190,7 @@ module ActiveScaffold
190
190
  # if the opposite association is a :belongs_to (in that case association in this class must be has_one or has_many)
191
191
  # then only show records that have not been associated yet
192
192
  if [:has_one, :has_many].include?(column.association.macro)
193
- params.merge!({column.association.primary_key_name => ''})
193
+ params.merge!({column.association.foreign_key => ''})
194
194
  end
195
195
 
196
196
  record_select_options = {:controller => remote_controller, :id => options[:id]}
@@ -245,7 +245,7 @@ module ActiveScaffold
245
245
  # add functionality for overriding subform partials from association class path
246
246
  def override_subform_partial?(column, subform_partial)
247
247
  path, partial_name = partial_pieces(override_subform_partial(column, subform_partial))
248
- template_exists?(partial_name, path, true)
248
+ template_exists?(partial_name, path)
249
249
  end
250
250
 
251
251
  def override_subform_partial(column, subform_partial)
@@ -254,7 +254,7 @@ module ActiveScaffold
254
254
 
255
255
  def override_form_field_partial?(column)
256
256
  path, partial_name = partial_pieces(override_form_field_partial(column))
257
- template_exists?(partial_name, path, true)
257
+ template_exists?(partial_name, path)
258
258
  end
259
259
 
260
260
  # the naming convention for overriding form fields with partials
@@ -17,14 +17,12 @@ module ActiveScaffold
17
17
  "#{column.active_record_class.human_attribute_name(column.name)} #{as_(value[:opt].downcase).downcase} #{format_number_value(controller.class.condition_value_for_numeric(column, value[:from]), column.options)} #{value[:opt] == 'BETWEEN' ? '- ' + format_number_value(controller.class.condition_value_for_numeric(column, value[:to]), column.options).to_s : ''}"
18
18
  when :string
19
19
  opt = ActiveScaffold::Finder::StringComparators.index(value[:opt]) || value[:opt]
20
- "#{column.active_record_class.human_attribute_name(column.name)} #{as_(opt).downcase} '#{column.stripped_value(value[:from])}' #{opt == 'BETWEEN' ? '- ' + column.stripped_value(value[:to]).to_s : ''}"
20
+ "#{column.active_record_class.human_attribute_name(column.name)} #{as_(opt).downcase} '#{value[:from]}' #{opt == 'BETWEEN' ? '- ' + value[:to].to_s : ''}"
21
21
  when :date, :time, :datetime, :timestamp
22
22
  conversion = column.column.type == :date ? :to_date : :to_time
23
23
  from = controller.condition_value_for_datetime(value[:from], conversion)
24
24
  to = controller.condition_value_for_datetime(value[:to], conversion)
25
- unless from.nil? || (value[:opt] == 'BETWEEN' && to.nil?)
26
- "#{column.active_record_class.human_attribute_name(column.name)} #{as_(value[:opt])} #{I18n.l(from)} #{value[:opt] == 'BETWEEN' ? '- ' + I18n.l(to) : ''}"
27
- end
25
+ "#{column.active_record_class.human_attribute_name(column.name)} #{as_(value[:opt])} #{I18n.l(from)} #{value[:opt] == 'BETWEEN' ? '- ' + I18n.l(to) : ''}"
28
26
  when :select, :multi_select, :record_select
29
27
  associated = value
30
28
  associated = [associated].compact unless associated.is_a? Array
@@ -10,7 +10,7 @@ module ActiveScaffold
10
10
  # we only pass the record as the argument. we previously also passed the formatted_value,
11
11
  # but mike perham pointed out that prohibited the usage of overrides to improve on the
12
12
  # performance of our default formatting. see issue #138.
13
- send(column_override(column), record)
13
+ send(column_override(column), column, record)
14
14
  # second, check if the dev has specified a valid list_ui for this column
15
15
  elsif column.list_ui and override_column_ui?(column.list_ui)
16
16
  send(override_column_ui(column.list_ui), column, record)
@@ -42,6 +42,7 @@ module ActiveScaffold
42
42
  return text if link.crud_type.nil?
43
43
  url_options[:link] = as_(:create_new) if link.crud_type == :create
44
44
  end
45
+
45
46
  if column_link_authorized?(link, column, record, associated)
46
47
  render_action_link(link, url_options, record)
47
48
  else
@@ -123,7 +124,6 @@ module ActiveScaffold
123
124
  format_column_value(record, column)
124
125
  else
125
126
  value = record.send(column.name)
126
- value = value.to_s unless value.nil?
127
127
  text, val = column.options[:options].find {|text, val| (val || text).to_s == value}
128
128
  value = active_scaffold_translated_option(column, text, val).first if text
129
129
  format_column_value(record, column, value)
@@ -229,15 +229,16 @@ module ActiveScaffold
229
229
  end
230
230
 
231
231
  def cache_association(value, column)
232
+ # loaded? and target seems to be gone in rails 3.1
232
233
  # we are not using eager loading, cache firsts records in order not to query the database in a future
233
- unless value.loaded?
234
+ #unless value.loaded?
234
235
  # load at least one record, is needed for column_empty? and checking permissions
235
- if column.associated_limit.nil?
236
- Rails.logger.warn "ActiveScaffold: Enable eager loading for #{column.name} association to reduce SQL queries"
237
- else
238
- value.target = value.find(:all, :limit => column.associated_limit + 1, :select => column.select_columns)
239
- end
240
- end
236
+ # if column.associated_limit.nil?
237
+ # Rails.logger.warn "ActiveScaffold: Enable eager loading for #{column.name} association to reduce SQL queries"
238
+ # else
239
+ # value.target = value.find(:all, :limit => column.associated_limit + 1, :select => column.select_columns)
240
+ # end
241
+ #end
241
242
  end
242
243
 
243
244
  # ==========
@@ -315,17 +316,11 @@ module ActiveScaffold
315
316
  def mark_column_heading
316
317
  if active_scaffold_config.mark.mark_all_mode == :page then
317
318
  all_marked = true
318
- @records.each do |record|
319
+ @page.items.each do |record|
319
320
  all_marked = false if !marked_records.entries.include?(record.id)
320
321
  end
321
322
  else
322
- # if relation does not respond to kaminari total_count...
323
- # kaminari paging is nt active
324
- if @records.respond_to?(:total_count)
325
- all_marked = (marked_records.length >= @records.total_count)
326
- else
327
- all_marked = (marked_records.length >= @records.count)
328
- end
323
+ all_marked = (marked_records.length >= @page.pager.count)
329
324
  end
330
325
  tag_options = {:id => "#{controller_id}_mark_heading", :class => "mark_heading in_place_editor_field"}
331
326
  tag_options['data-ie_url'] = url_for({:controller => params_for[:controller], :action => 'mark_all', :eid => params[:eid]})
@@ -358,15 +353,14 @@ module ActiveScaffold
358
353
 
359
354
  def render_nested_view(action_links, url_options, record)
360
355
  rendered = []
361
- link_nested_controllers = []
362
356
  action_links.member.each do |link|
363
357
  if link.nested_link? && link.column && @nested_auto_open[link.column.name] && @records.length <= @nested_auto_open[link.column.name] && controller.respond_to?(:render_component_into_view)
364
- link_url_options = {:embedded => true, :format => :js}.merge(action_link_url_options(link, url_options, record, options = {:reuse_eid => true}))
365
- link_nested_controllers << link.controller.to_s if link.controller
366
- rendered << (controller.send(:render_component_into_view, link_url_options))
358
+ link_url_options = {:adapter => '_list_inline_adapter', :format => :js}.merge(action_link_url_options(link, url_options, record, options = {:reuse_eid => true}))
359
+ link_id = get_action_link_id(link_url_options, record, link.column)
360
+ rendered << (controller.send(:render_component_into_view, link_url_options) + javascript_tag("ActiveScaffold.ActionLink.get('#{link_id}').set_opened();"))
367
361
  end
368
362
  end
369
- content_tag(:tr, content_tag(:td, rendered.join(' ').html_safe), :class => "inline-adapter-autoopen", 'data-actionlink-controllers' => link_nested_controllers.join('::').html_safe, 'data-as_load'=>"tr");
363
+ rendered.join(' ').html_safe
370
364
  end
371
365
 
372
366
  end
@@ -74,7 +74,7 @@ module ActiveScaffold
74
74
  associated = html_options.delete :value
75
75
  if column.association
76
76
  associated = associated.is_a?(Array) ? associated.map(&:to_i) : associated.to_i unless associated.nil?
77
- method = column.association.macro == :belongs_to ? column.association.primary_key_name : column.name
77
+ method = column.association.macro == :belongs_to ? column.association.foreign_key : column.name
78
78
  select_options = options_for_association(column.association, true)
79
79
  else
80
80
  method = column.name
@@ -42,6 +42,28 @@ module ActiveScaffold
42
42
  end
43
43
  end
44
44
 
45
+ def partial_pieces(partial_path)
46
+ if partial_path.include?('/')
47
+ return File.dirname(partial_path), File.basename(partial_path)
48
+ else
49
+ return controller.class.controller_path, partial_path
50
+ end
51
+ end
52
+
53
+ # This is the template finder logic, keep it updated with however we find stuff in rails
54
+ # currently this very similar to the logic in ActionBase::Base.render for options file
55
+ # TODO: Work with rails core team to find a better way to check for this.
56
+ # Not working so far for rais 3.1
57
+ def template_exists?(template_name, path)
58
+ begin
59
+ method = 'find_template'
60
+ #self.view_paths.send(method, template_name)
61
+ return false
62
+ rescue ActionView::MissingTemplate => e
63
+ return false
64
+ end
65
+ end
66
+
45
67
  def generate_temporary_id
46
68
  (Time.now.to_f*1000).to_i.to_s
47
69
  end
@@ -113,7 +135,7 @@ module ActiveScaffold
113
135
 
114
136
  # a general-use loading indicator (the "stuff is happening, please wait" feedback)
115
137
  def loading_indicator_tag(options)
116
- image_tag "/images/active_scaffold/default/indicator.gif", :style => "visibility:hidden;", :id => loading_indicator_id(options), :alt => "loading indicator", :class => "loading-indicator"
138
+ image_tag "indicator.gif", :style => "visibility:hidden;", :id => loading_indicator_id(options), :alt => "loading indicator", :class => "loading-indicator"
117
139
  end
118
140
 
119
141
  # Creates a javascript-based link that toggles the visibility of some element on the page.
@@ -127,7 +149,7 @@ module ActiveScaffold
127
149
  end
128
150
 
129
151
  def skip_action_link(link, *args)
130
- (!link.ignore_method.nil? && controller.respond_to?(link.ignore_method) && controller.send(link.ignore_method, *args)) || ((link.security_method_set? or controller.respond_to? link.security_method) and !controller.send(link.security_method, *args))
152
+ (!link.ignore_method.nil? and controller.try(link.ignore_method, *args)) || ((link.security_method_set? or controller.respond_to? link.security_method) and !controller.send(link.security_method, *args))
131
153
  end
132
154
 
133
155
  def render_action_link(link, url_options, record = nil, html_options = {})
@@ -140,12 +162,7 @@ module ActiveScaffold
140
162
  if link.type == :member && !options[:authorized]
141
163
  action_link_html(link, nil, {:class => "disabled #{link.action}#{link.html_options[:class].blank? ? '' : (' ' + link.html_options[:class])}"}, record)
142
164
  else
143
- begin
144
- render_action_link(link, url_options, record)
145
- rescue
146
- Rails.logger.error("render_action_link: exception occured: #{$!} link: #{link.inspect}, url_options: #{url_options.inspect}, options: #{options.inspect}, record: #{record.inspect}")
147
- action_link_html(link, nil, {:class => "disabled #{link.action}#{link.html_options[:class].blank? ? '' : (' ' + link.html_options[:class])}"}, record)
148
- end
165
+ render_action_link(link, url_options, record)
149
166
  end
150
167
  end
151
168
 
@@ -165,6 +182,7 @@ module ActiveScaffold
165
182
  end
166
183
 
167
184
  def action_link_html_options(link, url_options, record, html_options)
185
+ link_id = get_action_link_id(url_options, record, link.column)
168
186
  html_options.reverse_merge! link.html_options.merge(:class => link.action)
169
187
 
170
188
  # Needs to be in html_options to as the adding _method to the url is no longer supported by Rails
@@ -172,14 +190,20 @@ module ActiveScaffold
172
190
 
173
191
  html_options['data-confirm'] = link.confirm(record.try(:to_label)) if link.confirm?
174
192
  html_options['data-position'] = link.position if link.position and link.inline?
175
- html_options['data-controller'] = link.controller.to_s if link.controller
176
193
  html_options[:class] += ' as_action' if link.inline?
177
194
  html_options['data-action'] = link.action if link.inline?
178
195
  if link.popup?
179
196
  html_options['data-popup'] = true
180
197
  html_options[:target] = '_blank'
181
198
  end
199
+ html_options[:id] = link_id
182
200
  html_options[:remote] = true unless link.page? || link.popup?
201
+ if link.dhtml_confirm?
202
+ html_options[:class] += ' as_action' if !link.inline?
203
+ html_options[:page_link] = 'true' if !link.inline?
204
+ html_options[:dhtml_confirm] = link.dhtml_confirm.value
205
+ html_options[:onclick] = link.dhtml_confirm.onclick_function(controller, link_id)
206
+ end
183
207
  html_options[:class] += " #{link.html_options[:class]}" unless link.html_options[:class].blank?
184
208
  html_options
185
209
  end
@@ -239,7 +263,6 @@ module ActiveScaffold
239
263
  end
240
264
 
241
265
  def column_class(column, column_value, record)
242
- @numeric_classes ||= [:decimal, :float, :integer]
243
266
  classes = []
244
267
  classes << "#{column.name}-column"
245
268
  if column.css_class.is_a?(Proc)
@@ -251,7 +274,7 @@ module ActiveScaffold
251
274
 
252
275
  classes << 'empty' if column_empty? column_value
253
276
  classes << 'sorted' if active_scaffold_config.list.user.sorting.sorts_on?(column)
254
- classes << 'numeric' if column.column && @numeric_classes.include?(column.column.type)
277
+ classes << 'numeric' if column.column and [:decimal, :float, :integer].include?(column.column.type)
255
278
  classes.join(' ').rstrip
256
279
  end
257
280
 
@@ -270,10 +293,9 @@ module ActiveScaffold
270
293
  end
271
294
 
272
295
  def column_empty?(column_value)
273
- @empty_column_strings ||= ['&nbsp;', active_scaffold_config.list.empty_field_text]
274
296
  empty = column_value.nil?
275
297
  empty ||= column_value.empty? if column_value.respond_to? :empty?
276
- empty ||= @empty_column_strings.include?(column_value) if String === column_value
298
+ empty ||= ['&nbsp;', active_scaffold_config.list.empty_field_text].include? column_value if String === column_value
277
299
  return empty
278
300
  end
279
301