active_scaffold 3.4.17 → 3.4.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (183) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +12 -1
  3. data/README.md +8 -4
  4. data/app/assets/javascripts/jquery/active_scaffold.js +82 -67
  5. data/app/assets/stylesheets/active_scaffold.scss +1 -1
  6. data/app/assets/stylesheets/active_scaffold_colors.scss +1 -1
  7. data/app/assets/stylesheets/blue-theme.css +1 -1
  8. data/app/views/active_scaffold_overrides/_form_association.html.erb +3 -3
  9. data/app/views/active_scaffold_overrides/_form_association_record.html.erb +3 -3
  10. data/app/views/active_scaffold_overrides/_show_columns.html.erb +1 -1
  11. data/lib/active_scaffold.rb +16 -16
  12. data/lib/active_scaffold/actions/common_search.rb +13 -11
  13. data/lib/active_scaffold/actions/core.rb +85 -78
  14. data/lib/active_scaffold/actions/create.rb +29 -28
  15. data/lib/active_scaffold/actions/delete.rb +17 -17
  16. data/lib/active_scaffold/actions/field_search.rb +18 -19
  17. data/lib/active_scaffold/actions/list.rb +30 -22
  18. data/lib/active_scaffold/actions/mark.rb +1 -1
  19. data/lib/active_scaffold/actions/nested.rb +78 -65
  20. data/lib/active_scaffold/actions/search.rb +13 -10
  21. data/lib/active_scaffold/actions/show.rb +10 -6
  22. data/lib/active_scaffold/actions/subform.rb +1 -2
  23. data/lib/active_scaffold/actions/update.rb +39 -31
  24. data/lib/active_scaffold/active_record_permissions.rb +14 -15
  25. data/lib/active_scaffold/attribute_params.rb +42 -43
  26. data/lib/active_scaffold/bridges.rb +22 -12
  27. data/lib/active_scaffold/bridges/ancestry.rb +1 -1
  28. data/lib/active_scaffold/bridges/ancestry/ancestry_bridge.rb +6 -6
  29. data/lib/active_scaffold/bridges/bitfields.rb +1 -1
  30. data/lib/active_scaffold/bridges/bitfields/bitfields_bridge.rb +12 -13
  31. data/lib/active_scaffold/bridges/calendar_date_select.rb +5 -5
  32. data/lib/active_scaffold/bridges/calendar_date_select/as_cds_bridge.rb +17 -20
  33. data/lib/active_scaffold/bridges/cancan.rb +1 -1
  34. data/lib/active_scaffold/bridges/cancan/cancan_bridge.rb +8 -9
  35. data/lib/active_scaffold/bridges/carrierwave.rb +4 -4
  36. data/lib/active_scaffold/bridges/carrierwave/carrierwave_bridge.rb +9 -8
  37. data/lib/active_scaffold/bridges/carrierwave/form_ui.rb +11 -10
  38. data/lib/active_scaffold/bridges/carrierwave/list_ui.rb +7 -6
  39. data/lib/active_scaffold/bridges/chosen.rb +1 -1
  40. data/lib/active_scaffold/bridges/chosen/helpers.rb +4 -4
  41. data/lib/active_scaffold/bridges/country_helper.rb +1 -1
  42. data/lib/active_scaffold/bridges/country_helper/country_helper_bridge.rb +259 -260
  43. data/lib/active_scaffold/bridges/date_picker.rb +2 -2
  44. data/lib/active_scaffold/bridges/date_picker/ext.rb +9 -11
  45. data/lib/active_scaffold/bridges/date_picker/helper.rb +61 -67
  46. data/lib/active_scaffold/bridges/dragonfly.rb +4 -4
  47. data/lib/active_scaffold/bridges/dragonfly/dragonfly_bridge.rb +9 -8
  48. data/lib/active_scaffold/bridges/dragonfly/form_ui.rb +11 -10
  49. data/lib/active_scaffold/bridges/dragonfly/list_ui.rb +6 -5
  50. data/lib/active_scaffold/bridges/file_column.rb +5 -5
  51. data/lib/active_scaffold/bridges/file_column/as_file_column_bridge.rb +20 -23
  52. data/lib/active_scaffold/bridges/file_column/file_column_helpers.rb +20 -23
  53. data/lib/active_scaffold/bridges/file_column/form_ui.rb +13 -14
  54. data/lib/active_scaffold/bridges/file_column/list_ui.rb +7 -8
  55. data/lib/active_scaffold/bridges/file_column/test/functional/file_column_keep_test.rb +18 -22
  56. data/lib/active_scaffold/bridges/file_column/test/mock_model.rb +5 -4
  57. data/lib/active_scaffold/bridges/file_column/test/test_helper.rb +2 -10
  58. data/lib/active_scaffold/bridges/paper_trail.rb +7 -5
  59. data/lib/active_scaffold/bridges/paper_trail/paper_trail_bridge.rb +4 -3
  60. data/lib/active_scaffold/bridges/paperclip.rb +5 -5
  61. data/lib/active_scaffold/bridges/paperclip/form_ui.rb +11 -10
  62. data/lib/active_scaffold/bridges/paperclip/list_ui.rb +6 -5
  63. data/lib/active_scaffold/bridges/paperclip/paperclip_bridge.rb +10 -9
  64. data/lib/active_scaffold/bridges/record_select.rb +1 -1
  65. data/lib/active_scaffold/bridges/record_select/helpers.rb +28 -28
  66. data/lib/active_scaffold/bridges/semantic_attributes.rb +1 -1
  67. data/lib/active_scaffold/bridges/semantic_attributes/column.rb +1 -1
  68. data/lib/active_scaffold/bridges/shared/date_bridge.rb +58 -52
  69. data/lib/active_scaffold/bridges/tiny_mce.rb +2 -2
  70. data/lib/active_scaffold/bridges/tiny_mce/helpers.rb +3 -3
  71. data/lib/active_scaffold/config/base.rb +9 -10
  72. data/lib/active_scaffold/config/core.rb +24 -29
  73. data/lib/active_scaffold/config/create.rb +0 -1
  74. data/lib/active_scaffold/config/field_search.rb +8 -10
  75. data/lib/active_scaffold/config/form.rb +5 -5
  76. data/lib/active_scaffold/config/list.rb +21 -20
  77. data/lib/active_scaffold/config/mark.rb +3 -3
  78. data/lib/active_scaffold/config/nested.rb +11 -10
  79. data/lib/active_scaffold/config/search.rb +2 -3
  80. data/lib/active_scaffold/config/show.rb +1 -1
  81. data/lib/active_scaffold/config/update.rb +1 -2
  82. data/lib/active_scaffold/configurable.rb +9 -11
  83. data/lib/active_scaffold/constraints.rb +9 -8
  84. data/lib/active_scaffold/core.rb +72 -84
  85. data/lib/active_scaffold/data_structures/action_columns.rb +26 -25
  86. data/lib/active_scaffold/data_structures/action_link.rb +43 -43
  87. data/lib/active_scaffold/data_structures/action_links.rb +17 -15
  88. data/lib/active_scaffold/data_structures/actions.rb +5 -5
  89. data/lib/active_scaffold/data_structures/bridge.rb +6 -3
  90. data/lib/active_scaffold/data_structures/column.rb +110 -89
  91. data/lib/active_scaffold/data_structures/columns.rb +3 -3
  92. data/lib/active_scaffold/data_structures/error_message.rb +4 -6
  93. data/lib/active_scaffold/data_structures/nested_info.rb +43 -48
  94. data/lib/active_scaffold/data_structures/set.rb +7 -8
  95. data/lib/active_scaffold/data_structures/sorting.rb +38 -33
  96. data/lib/active_scaffold/delayed_setup.rb +5 -6
  97. data/lib/active_scaffold/engine.rb +4 -4
  98. data/lib/active_scaffold/extensions/action_controller_rendering.rb +3 -4
  99. data/lib/active_scaffold/extensions/action_controller_rescueing.rb +1 -1
  100. data/lib/active_scaffold/extensions/action_view_rendering.rb +5 -6
  101. data/lib/active_scaffold/extensions/left_outer_joins.rb +11 -11
  102. data/lib/active_scaffold/extensions/localize.rb +1 -1
  103. data/lib/active_scaffold/extensions/name_option_for_datetime.rb +1 -1
  104. data/lib/active_scaffold/extensions/paginator_extensions.rb +2 -5
  105. data/lib/active_scaffold/extensions/reverse_associations.rb +13 -13
  106. data/lib/active_scaffold/extensions/routing_mapper.rb +9 -9
  107. data/lib/active_scaffold/extensions/unsaved_associated.rb +9 -9
  108. data/lib/active_scaffold/finder.rb +90 -93
  109. data/lib/active_scaffold/helpers/association_helpers.rb +5 -5
  110. data/lib/active_scaffold/helpers/controller_helpers.rb +22 -19
  111. data/lib/active_scaffold/helpers/form_column_helpers.rb +115 -105
  112. data/lib/active_scaffold/helpers/human_condition_helpers.rb +62 -35
  113. data/lib/active_scaffold/helpers/id_helpers.rb +6 -6
  114. data/lib/active_scaffold/helpers/list_column_helpers.rb +89 -94
  115. data/lib/active_scaffold/helpers/pagination_helpers.rb +9 -9
  116. data/lib/active_scaffold/helpers/search_column_helpers.rb +47 -44
  117. data/lib/active_scaffold/helpers/show_column_helpers.rb +2 -2
  118. data/lib/active_scaffold/helpers/view_helpers.rb +86 -91
  119. data/lib/active_scaffold/marked_model.rb +10 -10
  120. data/lib/active_scaffold/paginator.rb +30 -34
  121. data/lib/active_scaffold/responds_to_parent.rb +27 -28
  122. data/lib/active_scaffold/tableless.rb +20 -15
  123. data/lib/active_scaffold/version.rb +1 -1
  124. data/lib/generators/active_scaffold/active_scaffold_generator.rb +8 -8
  125. data/lib/generators/active_scaffold_controller/active_scaffold_controller_generator.rb +9 -9
  126. data/shoulda_macros/macros.rb +27 -22
  127. data/test/bridges/bridge_test.rb +38 -29
  128. data/test/bridges/date_picker_test.rb +1 -1
  129. data/test/bridges/paper_trail_test.rb +17 -0
  130. data/test/bridges/paperclip_test.rb +3 -2
  131. data/test/bridges/tiny_mce_test.rb +5 -2
  132. data/test/company.rb +25 -30
  133. data/test/config/base_test.rb +1 -1
  134. data/test/config/core_test.rb +9 -9
  135. data/test/config/create_test.rb +14 -8
  136. data/test/config/delete_test.rb +4 -4
  137. data/test/config/field_search_test.rb +6 -6
  138. data/test/config/list_test.rb +16 -16
  139. data/test/config/nested_test.rb +4 -4
  140. data/test/config/search_test.rb +8 -8
  141. data/test/config/show_test.rb +6 -6
  142. data/test/config/subform_test.rb +1 -1
  143. data/test/config/update_test.rb +5 -5
  144. data/test/const_mocker.rb +4 -4
  145. data/test/data_structures/action_columns_test.rb +4 -5
  146. data/test/data_structures/action_link_test.rb +1 -0
  147. data/test/data_structures/action_links_test.rb +5 -5
  148. data/test/data_structures/column_test.rb +9 -9
  149. data/test/data_structures/columns_test.rb +2 -2
  150. data/test/data_structures/error_message_test.rb +4 -5
  151. data/test/data_structures/set_test.rb +1 -2
  152. data/test/data_structures/sorting_test.rb +10 -10
  153. data/test/data_structures/validation_reflection_test.rb +8 -0
  154. data/test/extensions/routing_mapper_test.rb +2 -2
  155. data/test/helpers/list_column_helpers_test.rb +3 -2
  156. data/test/helpers/pagination_helpers_test.rb +5 -4
  157. data/test/helpers/search_column_helpers_test.rb +1 -1
  158. data/test/misc/active_record_permissions_test.rb +63 -50
  159. data/test/misc/attribute_params_test.rb +28 -26
  160. data/test/misc/calculation_test.rb +10 -3
  161. data/test/misc/configurable_test.rb +12 -13
  162. data/test/misc/constraints_test.rb +6 -6
  163. data/test/misc/convert_numbers_format_test.rb +7 -6
  164. data/test/misc/finder_test.rb +17 -12
  165. data/test/misc/lang_test.rb +3 -4
  166. data/test/misc/tableless_test.rb +2 -3
  167. data/test/mock_app/app/controllers/addresses_controller.rb +1 -1
  168. data/test/mock_app/app/controllers/buildings_controller.rb +1 -1
  169. data/test/mock_app/app/controllers/cars_controller.rb +1 -1
  170. data/test/mock_app/app/controllers/contacts_controller.rb +1 -1
  171. data/test/mock_app/app/controllers/people_controller.rb +1 -1
  172. data/test/mock_app/app/models/file_model.rb +2 -2
  173. data/test/mock_app/app/models/person.rb +1 -1
  174. data/test/mock_app/config/application.rb +3 -3
  175. data/test/mock_app/config/boot.rb +1 -1
  176. data/test/mock_app/config/environment.rb +1 -0
  177. data/test/mock_app/config/environments/development.rb +0 -1
  178. data/test/mock_app/config/environments/production.rb +1 -1
  179. data/test/mock_app/db/schema.rb +14 -15
  180. data/test/model_stub.rb +13 -16
  181. data/test/run_all.rb +5 -7
  182. data/test/test_helper.rb +12 -9
  183. metadata +19 -3
@@ -16,7 +16,7 @@ module ActiveScaffold
16
16
  end
17
17
 
18
18
  def reverse(klass = nil)
19
- unless defined? @reverse
19
+ unless defined? @reverse # rubocop:disable Style/IfUnlessModifier
20
20
  @reverse ||= inverse_of.try(:name)
21
21
  end
22
22
  @reverse || (autodetect_inverse(klass).try(:name) unless klass.nil?)
@@ -27,10 +27,10 @@ module ActiveScaffold
27
27
  klass ||= self.klass
28
28
 
29
29
  # name-based matching (association name vs self.active_record.to_s)
30
- matches = self.reverse_matches(klass)
30
+ matches = reverse_matches(klass)
31
31
  if matches.length > 1
32
32
  matches.find_all do |assoc|
33
- self.active_record.to_s.underscore.include? assoc.name.to_s.pluralize.singularize
33
+ active_record.to_s.underscore.include? assoc.name.to_s.pluralize.singularize
34
34
  end
35
35
  end
36
36
 
@@ -42,8 +42,9 @@ module ActiveScaffold
42
42
  def self.included(base)
43
43
  base.send :include, ActiveScaffold::ReverseAssociation::CommonMethods
44
44
  end
45
-
45
+
46
46
  protected
47
+
47
48
  def reverse_matches(klass)
48
49
  reverse_matches = []
49
50
 
@@ -52,20 +53,20 @@ module ActiveScaffold
52
53
  next if assoc == self
53
54
  # skip over has_many :through associations
54
55
  next if assoc.options[:through]
55
- next unless assoc.options[:polymorphic] or assoc.class_name == self.active_record.name
56
+ next unless assoc.options[:polymorphic] || assoc.class_name == active_record.name
56
57
 
57
- case [assoc.macro, self.macro].find_all{|m| m == :has_and_belongs_to_many}.length
58
+ case [assoc.macro, macro].find_all { |m| m == :has_and_belongs_to_many }.length
58
59
  # if both are a habtm, then match them based on the join table
59
60
  when 2
60
- next unless assoc.options[:join_table] == self.options[:join_table]
61
+ next unless assoc.options[:join_table] == options[:join_table]
61
62
 
62
63
  # if only one is a habtm, they do not match
63
64
  when 1
64
- next
65
+ next
65
66
 
66
67
  # otherwise, match them based on the foreign_key
67
68
  when 0
68
- next unless assoc.foreign_key.to_sym == self.foreign_key.to_sym
69
+ next unless assoc.foreign_key.to_sym == foreign_key.to_sym
69
70
  end
70
71
 
71
72
  reverse_matches << assoc
@@ -89,15 +90,14 @@ module ActiveScaffold
89
90
  next if assoc == self
90
91
  # only iterate has_many :through associations
91
92
  next unless assoc.options[:through]
92
- next unless assoc.class_name == self.active_record.name
93
- next unless assoc.through_reflection.class_name == self.through_reflection.class_name
94
-
93
+ next unless assoc.class_name == active_record.name
94
+ next unless assoc.through_reflection.class_name == through_reflection.class_name
95
+
95
96
  reverse_matches << assoc
96
97
  end
97
98
  reverse_matches
98
99
  end
99
100
  end
100
-
101
101
  end
102
102
  end
103
103
 
@@ -1,14 +1,14 @@
1
1
  module ActionDispatch
2
2
  module Routing
3
3
  ACTIVE_SCAFFOLD_CORE_ROUTING = {
4
- :collection => {:show_search => :get, :render_field => :post, :mark => :post},
5
- :member => {:update_column => :post, :render_field => [:get, :post], :mark => :post}
4
+ :collection => {:show_search => :get, :render_field => :post, :mark => :post},
5
+ :member => {:update_column => :post, :render_field => [:get, :post], :mark => :post}
6
6
  }
7
7
  ACTIVE_SCAFFOLD_ASSOCIATION_ROUTING = {
8
- :collection => {:edit_associated => :get, :new_existing => :get, :add_existing => :post},
9
- :member => {:edit_associated => :get, :destroy_existing => :delete}
8
+ :collection => {:edit_associated => :get, :new_existing => :get, :add_existing => :post},
9
+ :member => {:edit_associated => :get, :destroy_existing => :delete}
10
10
  }
11
-
11
+
12
12
  class Mapper
13
13
  module Resources
14
14
  class ActiveScaffold < Resource
@@ -39,10 +39,10 @@ module ActionDispatch
39
39
  end
40
40
  as_association_routes if opts[:association]
41
41
  end
42
-
42
+
43
43
  def as_association_routes
44
44
  resource_scope(:resource, ActiveScaffoldAssociation.new(parent_resource.name, parent_resource.options)) do
45
- collection do
45
+ collection do
46
46
  ActionDispatch::Routing::ACTIVE_SCAFFOLD_ASSOCIATION_ROUTING[:collection].each do |name, type|
47
47
  match(name, :via => type) if parent_resource.actions.include? name
48
48
  end
@@ -54,14 +54,14 @@ module ActionDispatch
54
54
  end
55
55
  end
56
56
  end
57
-
57
+
58
58
  def as_nested_resources(*resources)
59
59
  options = resources.extract_options!
60
60
  resources.each do |resource|
61
61
  resources(resource, options.merge(:parent_scaffold => merge_module_scope(@scope[:module], parent_resource.plural), :association => resource)) { yield if block_given? }
62
62
  end
63
63
  end
64
-
64
+
65
65
  def as_scoped_routes(*scopes)
66
66
  options = scopes.extract_options!
67
67
  scopes.each do |scope|
@@ -9,15 +9,15 @@ class ActiveRecord::Base
9
9
  end
10
10
 
11
11
  def save_associated
12
- with_unsaved_associated { |a| a.save and a.save_associated }
12
+ with_unsaved_associated { |a| a.save && a.save_associated }
13
13
  end
14
14
 
15
15
  def save_associated!
16
- save_associated or raise(ActiveRecord::RecordNotSaved)
16
+ save_associated || raise(ActiveRecord::RecordNotSaved)
17
17
  end
18
18
 
19
19
  def no_errors_in_associated?
20
- with_unsaved_associated {|a| a.errors.count == 0 and a.no_errors_in_associated?}
20
+ with_unsaved_associated { |a| a.errors.count == 0 && a.no_errors_in_associated? }
21
21
  end
22
22
 
23
23
  protected
@@ -33,10 +33,10 @@ class ActiveRecord::Base
33
33
  #
34
34
  # Otherwise the default behaviour of traversing all associations will be preserved.
35
35
  def associations_for_update
36
- if self.respond_to?( :scaffold_update_nofollow )
37
- self.class.reflect_on_all_associations.reject { |association| self.scaffold_update_nofollow.include?( association.name ) }
38
- elsif self.respond_to?( :scaffold_update_follow )
39
- self.class.reflect_on_all_associations.select { |association| self.scaffold_update_follow.include?( association.name ) }
36
+ if self.respond_to?(:scaffold_update_nofollow)
37
+ self.class.reflect_on_all_associations.reject { |association| scaffold_update_nofollow.include?(association.name) }
38
+ elsif self.respond_to?(:scaffold_update_follow)
39
+ self.class.reflect_on_all_associations.select { |association| scaffold_update_follow.include?(association.name) }
40
40
  else
41
41
  self.class.reflect_on_all_associations
42
42
  end
@@ -49,11 +49,11 @@ class ActiveRecord::Base
49
49
  # returns true otherwise, even when none of the associations have been instantiated. build wrapper methods accordingly.
50
50
  def with_unsaved_associated
51
51
  associations_for_update.all? do |assoc|
52
- association_proxy = self.association(assoc.name)
52
+ association_proxy = association(assoc.name)
53
53
  if association_proxy.target.present?
54
54
  records = association_proxy.target
55
55
  records = [records] unless records.is_a? Array # convert singular associations into collections for ease of use
56
- records.select {|r| r.unsaved? and not r.readonly?}.all? {|r| yield r} # must use select instead of find_all, which Rails overrides on association proxies for db access
56
+ records.select { |r| r.unsaved? && !r.readonly? }.all? { |r| yield r } # must use select instead of find_all, which Rails overrides on association proxies for db access
57
57
  else
58
58
  true
59
59
  end
@@ -1,7 +1,7 @@
1
1
  module ActiveScaffold
2
2
  module Finder
3
3
  def self.like_operator
4
- @@like_operator ||= ::ActiveRecord::Base.connection.adapter_name == "PostgreSQL" ? "ILIKE" : "LIKE"
4
+ @@like_operator ||= ::ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' ? 'ILIKE' : 'LIKE'
5
5
  end
6
6
 
7
7
  module ClassMethods
@@ -24,11 +24,10 @@ module ActiveScaffold
24
24
  phrase = where_clauses.join(' OR ')
25
25
 
26
26
  tokens.collect do |value|
27
- columns.inject([phrase]) do |condition, column|
27
+ columns.each_with_object([phrase]) do |column, condition|
28
28
  Array(column.search_sql).size.times do
29
29
  condition.push(column.text? ? like_pattern.sub('?', value) : ActiveScaffold::Core.column_type_cast(value, column.column))
30
30
  end
31
- condition
32
31
  end
33
32
  end
34
33
  end
@@ -39,57 +38,62 @@ module ActiveScaffold
39
38
  def condition_for_column(column, value, text_search = :full)
40
39
  like_pattern = like_pattern(text_search)
41
40
  if self.respond_to?("condition_for_#{column.name}_column")
42
- return self.send("condition_for_#{column.name}_column", column, value, like_pattern)
41
+ return send("condition_for_#{column.name}_column", column, value, like_pattern)
43
42
  end
44
- return unless column and column.search_sql and not value.blank?
43
+ return unless column && column.search_sql && !value.blank?
45
44
  search_ui = column.search_ui || column.column.try(:type)
46
45
  begin
47
- sql, *values = if search_ui && self.respond_to?("condition_for_#{search_ui}_type")
48
- self.send("condition_for_#{search_ui}_type", column, value, like_pattern)
49
- else
50
- if column.search_sql.instance_of? Proc
51
- column.search_sql.call(value)
46
+ sql, *values =
47
+ if search_ui && self.respond_to?("condition_for_#{search_ui}_type")
48
+ send("condition_for_#{search_ui}_type", column, value, like_pattern)
52
49
  else
53
- case search_ui
54
- when :boolean, :checkbox
55
- ["%{search_sql} = ?", column.column ? ActiveScaffold::Core.column_type_cast(value, column.column) : value]
56
- when :integer, :decimal, :float
57
- condition_for_numeric(column, value)
58
- when :string, :range
59
- condition_for_range(column, value, like_pattern)
60
- when :date, :time, :datetime, :timestamp
61
- condition_for_datetime(column, value)
62
- when :select, :multi_select, :country, :usa_state, :chosen, :multi_chosen
63
- ["%{search_sql} in (?)", Array(value)]
50
+ if column.search_sql.instance_of? Proc
51
+ column.search_sql.call(value)
64
52
  else
65
- if column.text?
66
- ["%{search_sql} #{ActiveScaffold::Finder.like_operator} ?", like_pattern.sub('?', value)]
67
- else
68
- ["%{search_sql} = ?", ActiveScaffold::Core.column_type_cast(value, column.column)]
69
- end
53
+ condition_for_search_ui(column, value, like_pattern, search_ui)
70
54
  end
71
55
  end
72
- end
73
56
  return nil unless sql
74
57
 
75
58
  conditions = [column.search_sql.collect { |search_sql| sql % {:search_sql => search_sql} }.join(' OR ')]
76
- conditions += values*column.search_sql.size if values.present?
59
+ conditions += values * column.search_sql.size if values.present?
77
60
  conditions
78
- rescue Exception => e
79
- logger.error "#{e.class.name}: #{e.message} -- on the ActiveScaffold column :#{column.name}, search_ui = #{search_ui} in #{self.name}"
61
+ rescue StandardError => e
62
+ logger.error "#{e.class.name}: #{e.message} -- on the ActiveScaffold column :#{column.name}, search_ui = #{search_ui} in #{name}"
80
63
  raise e
81
64
  end
82
65
  end
83
66
 
67
+ def condition_for_search_ui(column, value, like_pattern, search_ui)
68
+ case search_ui
69
+ when :boolean, :checkbox
70
+ ['%{search_sql} = ?', column.column ? ActiveScaffold::Core.column_type_cast(value, column.column) : value]
71
+ when :integer, :decimal, :float
72
+ condition_for_numeric(column, value)
73
+ when :string, :range
74
+ condition_for_range(column, value, like_pattern)
75
+ when :date, :time, :datetime, :timestamp
76
+ condition_for_datetime(column, value)
77
+ when :select, :multi_select, :country, :usa_state, :chosen, :multi_chosen
78
+ ['%{search_sql} in (?)', Array(value)]
79
+ else
80
+ if column.text?
81
+ ["%{search_sql} #{ActiveScaffold::Finder.like_operator} ?", like_pattern.sub('?', value)]
82
+ else
83
+ ['%{search_sql} = ?', ActiveScaffold::Core.column_type_cast(value, column.column)]
84
+ end
85
+ end
86
+ end
87
+
84
88
  def condition_for_numeric(column, value)
85
89
  if !value.is_a?(Hash)
86
- ["%{search_sql} = ?", condition_value_for_numeric(column, value)]
87
- elsif ActiveScaffold::Finder::NullComparators.include?(value[:opt])
90
+ ['%{search_sql} = ?', condition_value_for_numeric(column, value)]
91
+ elsif ActiveScaffold::Finder::NULL_COMPARATORS.include?(value[:opt])
88
92
  condition_for_null_type(column, value[:opt])
89
- elsif value[:from].blank? or not ActiveScaffold::Finder::NumericComparators.include?(value[:opt])
93
+ elsif value[:from].blank? || !ActiveScaffold::Finder::NUMERIC_COMPARATORS.include?(value[:opt])
90
94
  nil
91
95
  elsif value[:opt] == 'BETWEEN'
92
- ["(%{search_sql} BETWEEN ? AND ?)", condition_value_for_numeric(column, value[:from]), condition_value_for_numeric(column, value[:to])]
96
+ ['(%{search_sql} BETWEEN ? AND ?)', condition_value_for_numeric(column, value[:from]), condition_value_for_numeric(column, value[:to])]
93
97
  else
94
98
  ["%{search_sql} #{value[:opt]} ?", condition_value_for_numeric(column, value[:from])]
95
99
  end
@@ -100,20 +104,18 @@ module ActiveScaffold
100
104
  if column.text?
101
105
  ["%{search_sql} #{ActiveScaffold::Finder.like_operator} ?", like_pattern.sub('?', value)]
102
106
  else
103
- ["%{search_sql} = ?", ActiveScaffold::Core.column_type_cast(value, column.column)]
107
+ ['%{search_sql} = ?', ActiveScaffold::Core.column_type_cast(value, column.column)]
104
108
  end
105
- elsif ActiveScaffold::Finder::NullComparators.include?(value[:opt])
109
+ elsif ActiveScaffold::Finder::NULL_COMPARATORS.include?(value[:opt])
106
110
  condition_for_null_type(column, value[:opt], like_pattern)
107
111
  elsif value[:from].blank?
108
112
  nil
109
- elsif ActiveScaffold::Finder::StringComparators.values.include?(value[:opt])
113
+ elsif ActiveScaffold::Finder::STRING_COMPARATORS.values.include?(value[:opt])
110
114
  ["%{search_sql} #{ActiveScaffold::Finder.like_operator} ?", value[:opt].sub('?', value[:from])]
111
115
  elsif value[:opt] == 'BETWEEN'
112
- ["(%{search_sql} BETWEEN ? AND ?)", value[:from], value[:to]]
113
- elsif ActiveScaffold::Finder::NumericComparators.include?(value[:opt])
116
+ ['(%{search_sql} BETWEEN ? AND ?)', value[:from], value[:to]]
117
+ elsif ActiveScaffold::Finder::NUMERIC_COMPARATORS.include?(value[:opt])
114
118
  ["%{search_sql} #{value[:opt]} ?", value[:from]]
115
- else
116
- nil
117
119
  end
118
120
  end
119
121
 
@@ -135,7 +137,7 @@ module ActiveScaffold
135
137
 
136
138
  def condition_value_for_datetime(column, value, conversion = :to_time)
137
139
  if value.is_a? Hash
138
- Time.zone.local(*[:year, :month, :day, :hour, :minute, :second].collect {|part| value[part].to_i}) rescue nil
140
+ Time.zone.local(*[:year, :month, :day, :hour, :minute, :second].collect { |part| value[part].to_i }) rescue nil
139
141
  elsif value.respond_to?(:strftime)
140
142
  if conversion == :to_time
141
143
  # Explicitly get the current zone, because TimeWithZone#to_time in rails 3.2.3 returns UTC.
@@ -150,11 +152,11 @@ module ActiveScaffold
150
152
  parts = Date._parse(value)
151
153
  format = I18n.translate "time.formats.#{column.options[:format] || :picker}", :default => '' if ActiveScaffold.js_framework == :jquery
152
154
  if format.blank?
153
- time_parts = [[:hour, '%H'], [:min, '%M'], [:sec, '%S']].collect {|part, format_part| format_part if parts[part].present?}.compact
155
+ time_parts = [[:hour, '%H'], [:min, '%M'], [:sec, '%S']].collect { |part, format_part| format_part if parts[part].present? }.compact
154
156
  format = "#{I18n.t('date.formats.default')} #{time_parts.join(':')} #{'%z' if parts[:offset].present?}"
155
157
  else
156
158
  if parts[:hour]
157
- [[:min, '%M'], [:sec, '%S']].each {|part, f| format.gsub!(":#{f}", '') unless parts[part].present?}
159
+ [[:min, '%M'], [:sec, '%S']].each { |part, f| format.gsub!(":#{f}", '') unless parts[part].present? }
158
160
  else
159
161
  value += ' 00:00:00'
160
162
  end
@@ -198,33 +200,31 @@ module ActiveScaffold
198
200
  from_value = condition_value_for_datetime(column, value[:from], conversion)
199
201
  to_value = condition_value_for_datetime(column, value[:to], conversion)
200
202
 
201
- if from_value.nil? and to_value.nil?
203
+ if from_value.nil? && to_value.nil?
202
204
  nil
203
205
  elsif !from_value
204
- ["%{search_sql} <= ?", to_value.to_s(:db)]
206
+ ['%{search_sql} <= ?', to_value.to_s(:db)]
205
207
  elsif !to_value
206
- ["%{search_sql} >= ?", from_value.to_s(:db)]
208
+ ['%{search_sql} >= ?', from_value.to_s(:db)]
207
209
  else
208
- ["%{search_sql} BETWEEN ? AND ?", from_value.to_s(:db), to_value.to_s(:db)]
210
+ ['%{search_sql} BETWEEN ? AND ?', from_value.to_s(:db), to_value.to_s(:db)]
209
211
  end
210
212
  end
211
213
 
212
214
  def condition_for_record_select_type(column, value, like_pattern = nil)
213
215
  if value.is_a?(Array)
214
- ["%{search_sql} IN (?)", value]
216
+ ['%{search_sql} IN (?)', value]
215
217
  else
216
- ["%{search_sql} = ?", value]
218
+ ['%{search_sql} = ?', value]
217
219
  end
218
220
  end
219
221
 
220
222
  def condition_for_null_type(column, value, like_pattern = nil)
221
- case value.to_sym
222
- when :null
223
- ["%{search_sql} is null", []]
224
- when :not_null
225
- ["%{search_sql} is not null", []]
226
- else
227
- nil
223
+ case value.to_s
224
+ when 'null'
225
+ ['%{search_sql} is null', []]
226
+ when 'not_null'
227
+ ['%{search_sql} is not null', []]
228
228
  end
229
229
  end
230
230
 
@@ -238,7 +238,7 @@ module ActiveScaffold
238
238
  end
239
239
  end
240
240
 
241
- NumericComparators = [
241
+ NUMERIC_COMPARATORS = [
242
242
  '=',
243
243
  '>=',
244
244
  '<=',
@@ -247,17 +247,12 @@ module ActiveScaffold
247
247
  '!=',
248
248
  'BETWEEN'
249
249
  ]
250
- StringComparators = {
250
+ STRING_COMPARATORS = {
251
251
  :contains => '%?%',
252
252
  :begins_with => '?%',
253
253
  :ends_with => '%?'
254
254
  }
255
- NullComparators = [
256
- 'null',
257
- 'not_null'
258
- ]
259
-
260
-
255
+ NULL_COMPARATORS = %w(null not_null)
261
256
 
262
257
  def self.included(klass)
263
258
  klass.extend ClassMethods
@@ -282,7 +277,7 @@ module ActiveScaffold
282
277
 
283
278
  def active_scaffold_includes
284
279
  ActiveSupport::Deprecation.warn "active_scaffold_includes doesn't exist anymore, use active_scaffold_preload, active_scaffold_outer_joins or active_scaffold_references"
285
- self.active_scaffold_preload
280
+ active_scaffold_preload
286
281
  end
287
282
 
288
283
  attr_writer :active_scaffold_habtm_joins
@@ -335,7 +330,7 @@ module ActiveScaffold
335
330
  record = klass.find(id)
336
331
  security_options = {:crud_type => security_options.to_sym} unless security_options.is_a? Hash
337
332
  raise ActiveScaffold::RecordNotAllowed, "#{klass} with id = #{id}" unless record.authorized_for? security_options
338
- return record
333
+ record
339
334
  end
340
335
  # valid options may include:
341
336
  # * :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.
@@ -346,13 +341,15 @@ module ActiveScaffold
346
341
  full_includes = (active_scaffold_references.blank? ? nil : active_scaffold_references)
347
342
 
348
343
  # create a general-use options array that's compatible with Rails finders
349
- finder_options = { :reorder => options[:sorting].try(:clause),
350
- :conditions => search_conditions,
351
- :joins => joins_for_finder,
352
- :outer_joins => active_scaffold_outer_joins,
353
- :preload => active_scaffold_preload,
354
- :includes => full_includes,
355
- :select => options[:select]}
344
+ finder_options = {
345
+ :reorder => options[:sorting].try(:clause),
346
+ :conditions => search_conditions,
347
+ :joins => joins_for_finder,
348
+ :outer_joins => active_scaffold_outer_joins,
349
+ :preload => active_scaffold_preload,
350
+ :includes => full_includes,
351
+ :select => options[:select]
352
+ }
356
353
  if Rails::VERSION::MAJOR >= 4
357
354
  if options[:sorting].try(:sorts_by_sql?)
358
355
  options[:sorting].each do |col, _|
@@ -368,7 +365,7 @@ module ActiveScaffold
368
365
 
369
366
  def count_items(query, find_options = {}, count_includes = nil)
370
367
  count_includes ||= find_options[:includes] unless find_options[:conditions].blank?
371
- options = find_options.reject{|k,v| [:select, :reorder].include? k}
368
+ options = find_options.reject { |k, _| [:select, :reorder].include? k }
372
369
  # NOTE: we must use includes in the count query, because some conditions may reference other tables
373
370
  options[:includes] = count_includes
374
371
 
@@ -384,7 +381,7 @@ module ActiveScaffold
384
381
  # See finder_options for valid options
385
382
  def find_page(options = {})
386
383
  options.assert_valid_keys :sorting, :per_page, :page, :count_includes, :pagination, :select
387
- options[:per_page] ||= 999999999
384
+ options[:per_page] ||= 999_999_999
388
385
  options[:page] ||= 1
389
386
 
390
387
  find_options = finder_options(options)
@@ -397,7 +394,7 @@ module ActiveScaffold
397
394
 
398
395
  query = append_to_query(query, find_options)
399
396
  # we build the paginator differently for method- and sql-based sorting
400
- if options[:sorting] and options[:sorting].sorts_by_method?
397
+ if options[:sorting] && options[:sorting].sorts_by_method?
401
398
  pager = ::Paginator.new(count, options[:per_page]) do |offset, per_page|
402
399
  calculate_last_modified(query)
403
400
  sorted_collection = sort_collection_by_column(query.to_a, *options[:sorting].first)
@@ -415,9 +412,8 @@ module ActiveScaffold
415
412
  end
416
413
 
417
414
  def calculate_last_modified(query)
418
- if conditional_get_support? && query.klass.columns_hash['updated_at']
419
- @last_modified = query.maximum(:updated_at)
420
- end
415
+ return unless conditional_get_support? && query.klass.columns_hash['updated_at']
416
+ @last_modified = query.maximum(:updated_at)
421
417
  end
422
418
 
423
419
  def calculate_query
@@ -428,28 +424,29 @@ module ActiveScaffold
428
424
  outer_joins += includes if includes
429
425
  primary_key = active_scaffold_config.model.primary_key
430
426
  subquery = append_to_query(beginning_of_chain, :conditions => conditions, :joins => joins_for_finder, :outer_joins => outer_joins, :select => active_scaffold_config.columns[primary_key].field)
427
+ subquery = subquery.unscope(:order) if Rails::VERSION::MAJOR >= 4
431
428
  active_scaffold_config.model.where(primary_key => subquery)
432
429
  end
433
430
 
434
- def append_to_query(query, options)
431
+ def append_to_query(relation, options)
435
432
  options.assert_valid_keys :where, :select, :group, :reorder, :limit, :offset, :joins, :outer_joins, :includes, :lock, :readonly, :from, :conditions, :preload, (:references if Rails::VERSION::MAJOR >= 4)
436
- query = options.reject{|k,v| v.blank?}.inject(query) do |query, (k, v)|
437
- k == :conditions ? apply_conditions(query, *v) : query.send(k, v)
433
+ relation = options.reject { |_, v| v.blank? }.inject(relation) do |rel, (k, v)|
434
+ k == :conditions ? apply_conditions(rel, *v) : rel.send(k, v)
438
435
  end
439
436
  if options[:outer_joins].present?
440
437
  if Rails::VERSION::MAJOR >= 4
441
- query.distinct_value = true
438
+ relation.distinct_value = true
442
439
  else
443
- query = query.uniq
440
+ relation = relation.uniq
444
441
  end
445
442
  end
446
- query
443
+ relation
447
444
  end
448
445
 
449
446
  def joins_for_finder
450
447
  case joins_for_collection
451
448
  when String
452
- [ joins_for_collection ]
449
+ [joins_for_collection]
453
450
  when Array
454
451
  joins_for_collection
455
452
  else
@@ -457,12 +454,12 @@ module ActiveScaffold
457
454
  end + active_scaffold_habtm_joins
458
455
  end
459
456
 
460
- def apply_conditions(query, *conditions)
461
- conditions.reject(&:blank?).inject(query) do |query, condition|
457
+ def apply_conditions(relation, *conditions)
458
+ conditions.reject(&:blank?).inject(relation) do |rel, condition|
462
459
  if condition.is_a?(Array) && !condition.first.is_a?(String) # multiple conditions
463
- apply_conditions(query, *condition)
460
+ apply_conditions(rel, *condition)
464
461
  else
465
- query.where(condition)
462
+ rel.where(condition)
466
463
  end
467
464
  end
468
465
  end
@@ -470,11 +467,11 @@ module ActiveScaffold
470
467
  # TODO: this should reside on the column, not the controller
471
468
  def sort_collection_by_column(collection, column, order)
472
469
  sorter = column.sort[:method]
473
- collection = collection.sort_by { |record|
470
+ collection = collection.sort_by do |record|
474
471
  value = (sorter.is_a? Proc) ? record.instance_eval(&sorter) : record.instance_eval(sorter.to_s)
475
472
  value = '' if value.nil?
476
473
  value
477
- }
474
+ end
478
475
  collection.reverse! if order.downcase == 'desc'
479
476
  collection
480
477
  end