ransack 1.7.0 → 2.4.1

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 (127) hide show
  1. checksums.yaml +5 -5
  2. data/.github/FUNDING.yml +3 -0
  3. data/.github/SECURITY.md +12 -0
  4. data/.github/workflows/test.yml +120 -0
  5. data/.gitignore +3 -0
  6. data/CHANGELOG.md +463 -27
  7. data/CONTRIBUTING.md +52 -22
  8. data/Gemfile +24 -24
  9. data/README.md +453 -126
  10. data/Rakefile +6 -25
  11. data/lib/polyamorous/activerecord_5.2_ruby_2/join_association.rb +24 -0
  12. data/lib/polyamorous/activerecord_5.2_ruby_2/join_dependency.rb +79 -0
  13. data/lib/polyamorous/activerecord_5.2_ruby_2/reflection.rb +11 -0
  14. data/lib/polyamorous/activerecord_6.0_ruby_2/join_association.rb +1 -0
  15. data/lib/polyamorous/activerecord_6.0_ruby_2/join_dependency.rb +80 -0
  16. data/lib/polyamorous/activerecord_6.0_ruby_2/reflection.rb +1 -0
  17. data/lib/polyamorous/activerecord_6.1_ruby_2/join_association.rb +74 -0
  18. data/lib/polyamorous/activerecord_6.1_ruby_2/join_dependency.rb +93 -0
  19. data/lib/polyamorous/activerecord_6.1_ruby_2/reflection.rb +1 -0
  20. data/lib/polyamorous/join.rb +70 -0
  21. data/lib/polyamorous/polyamorous.rb +24 -0
  22. data/lib/polyamorous/swapping_reflection_class.rb +11 -0
  23. data/lib/polyamorous/tree_node.rb +7 -0
  24. data/lib/ransack/adapters/active_record/base.rb +27 -2
  25. data/lib/ransack/adapters/active_record/context.rb +213 -139
  26. data/lib/ransack/adapters/active_record/ransack/constants.rb +70 -55
  27. data/lib/ransack/adapters/active_record/ransack/context.rb +10 -18
  28. data/lib/ransack/adapters/active_record/ransack/nodes/condition.rb +42 -32
  29. data/lib/ransack/adapters/active_record/ransack/translate.rb +1 -5
  30. data/lib/ransack/adapters/active_record/ransack/visitor.rb +23 -0
  31. data/lib/ransack/adapters/active_record.rb +11 -10
  32. data/lib/ransack/adapters.rb +45 -23
  33. data/lib/ransack/configuration.rb +107 -4
  34. data/lib/ransack/constants.rb +13 -26
  35. data/lib/ransack/context.rb +45 -33
  36. data/lib/ransack/helpers/form_builder.rb +21 -12
  37. data/lib/ransack/helpers/form_helper.rb +75 -70
  38. data/lib/ransack/locale/ar.yml +70 -0
  39. data/lib/ransack/locale/az.yml +70 -0
  40. data/lib/ransack/locale/bg.yml +70 -0
  41. data/lib/ransack/locale/ca.yml +70 -0
  42. data/lib/ransack/locale/da.yml +70 -0
  43. data/lib/ransack/locale/el.yml +70 -0
  44. data/lib/ransack/locale/es.yml +22 -22
  45. data/lib/ransack/locale/fa.yml +70 -0
  46. data/lib/ransack/locale/fi.yml +71 -0
  47. data/lib/ransack/locale/id.yml +70 -0
  48. data/lib/ransack/locale/it.yml +70 -0
  49. data/lib/ransack/locale/ja.yml +70 -0
  50. data/lib/ransack/locale/nl.yml +4 -4
  51. data/lib/ransack/locale/pt-BR.yml +70 -0
  52. data/lib/ransack/locale/ru.yml +70 -0
  53. data/lib/ransack/locale/sk.yml +70 -0
  54. data/lib/ransack/locale/tr.yml +70 -0
  55. data/lib/ransack/locale/{zh.yml → zh-CN.yml} +13 -13
  56. data/lib/ransack/locale/zh-TW.yml +70 -0
  57. data/lib/ransack/nodes/attribute.rb +5 -2
  58. data/lib/ransack/nodes/bindable.rb +18 -6
  59. data/lib/ransack/nodes/condition.rb +85 -28
  60. data/lib/ransack/nodes/grouping.rb +17 -11
  61. data/lib/ransack/nodes/sort.rb +9 -5
  62. data/lib/ransack/nodes/value.rb +74 -68
  63. data/lib/ransack/nodes.rb +1 -1
  64. data/lib/ransack/predicate.rb +17 -20
  65. data/lib/ransack/search.rb +17 -8
  66. data/lib/ransack/translate.rb +115 -115
  67. data/lib/ransack/version.rb +1 -1
  68. data/lib/ransack/visitor.rb +1 -12
  69. data/lib/ransack.rb +9 -9
  70. data/logo/ransack-h.png +0 -0
  71. data/logo/ransack-h.svg +34 -0
  72. data/logo/ransack-v.png +0 -0
  73. data/logo/ransack-v.svg +34 -0
  74. data/logo/ransack.png +0 -0
  75. data/logo/ransack.svg +21 -0
  76. data/ransack.gemspec +7 -24
  77. data/spec/console.rb +4 -0
  78. data/spec/helpers/polyamorous_helper.rb +19 -0
  79. data/spec/polyamorous/join_association_spec.rb +35 -0
  80. data/spec/polyamorous/join_dependency_spec.rb +97 -0
  81. data/spec/polyamorous/join_spec.rb +19 -0
  82. data/spec/ransack/adapters/active_record/base_spec.rb +370 -75
  83. data/spec/ransack/adapters/active_record/context_spec.rb +72 -34
  84. data/spec/ransack/configuration_spec.rb +97 -14
  85. data/spec/ransack/helpers/form_builder_spec.rb +2 -11
  86. data/spec/ransack/helpers/form_helper_spec.rb +481 -113
  87. data/spec/ransack/nodes/condition_spec.rb +24 -0
  88. data/spec/ransack/nodes/grouping_spec.rb +56 -0
  89. data/spec/ransack/predicate_spec.rb +79 -5
  90. data/spec/ransack/search_spec.rb +207 -81
  91. data/spec/spec_helper.rb +8 -0
  92. data/spec/support/schema.rb +100 -42
  93. metadata +57 -184
  94. data/.travis.yml +0 -69
  95. data/lib/ransack/adapters/active_record/3.0/compat.rb +0 -179
  96. data/lib/ransack/adapters/active_record/3.0/context.rb +0 -201
  97. data/lib/ransack/adapters/active_record/3.1/context.rb +0 -215
  98. data/lib/ransack/adapters/active_record/3.2/context.rb +0 -44
  99. data/lib/ransack/adapters/active_record/compat.rb +0 -14
  100. data/lib/ransack/adapters/mongoid/3.2/.gitkeep +0 -0
  101. data/lib/ransack/adapters/mongoid/attributes/attribute.rb +0 -37
  102. data/lib/ransack/adapters/mongoid/attributes/order_predications.rb +0 -17
  103. data/lib/ransack/adapters/mongoid/attributes/predications.rb +0 -141
  104. data/lib/ransack/adapters/mongoid/base.rb +0 -130
  105. data/lib/ransack/adapters/mongoid/context.rb +0 -208
  106. data/lib/ransack/adapters/mongoid/inquiry_hash.rb +0 -23
  107. data/lib/ransack/adapters/mongoid/ransack/constants.rb +0 -88
  108. data/lib/ransack/adapters/mongoid/ransack/context.rb +0 -60
  109. data/lib/ransack/adapters/mongoid/ransack/nodes/condition.rb +0 -27
  110. data/lib/ransack/adapters/mongoid/ransack/translate.rb +0 -13
  111. data/lib/ransack/adapters/mongoid/ransack/visitor.rb +0 -24
  112. data/lib/ransack/adapters/mongoid/table.rb +0 -35
  113. data/lib/ransack/adapters/mongoid.rb +0 -13
  114. data/spec/mongoid/adapters/mongoid/base_spec.rb +0 -276
  115. data/spec/mongoid/adapters/mongoid/context_spec.rb +0 -56
  116. data/spec/mongoid/configuration_spec.rb +0 -102
  117. data/spec/mongoid/dependencies_spec.rb +0 -8
  118. data/spec/mongoid/helpers/ransack_helper.rb +0 -11
  119. data/spec/mongoid/nodes/condition_spec.rb +0 -34
  120. data/spec/mongoid/nodes/grouping_spec.rb +0 -13
  121. data/spec/mongoid/predicate_spec.rb +0 -155
  122. data/spec/mongoid/search_spec.rb +0 -446
  123. data/spec/mongoid/support/mongoid.yml +0 -6
  124. data/spec/mongoid/support/schema.rb +0 -128
  125. data/spec/mongoid/translate_spec.rb +0 -14
  126. data/spec/mongoid_spec_helper.rb +0 -59
  127. data/spec/ransack/dependencies_spec.rb +0 -12
data/Rakefile CHANGED
@@ -5,39 +5,20 @@ Bundler::GemHelper.install_tasks
5
5
 
6
6
  RSpec::Core::RakeTask.new(:spec) do |rspec|
7
7
  ENV['SPEC'] = 'spec/ransack/**/*_spec.rb'
8
- rspec.rspec_opts = ['--backtrace']
9
- end
10
-
11
- RSpec::Core::RakeTask.new(:mongoid) do |rspec|
12
- ENV['SPEC'] = 'spec/mongoid/**/*_spec.rb'
13
- rspec.rspec_opts = ['--backtrace']
8
+ # With Rails 3, using `--backtrace` raises 'invalid option' when testing.
9
+ # With Rails 4 and 5 it can be uncommented to see the backtrace:
10
+ #
11
+ # rspec.rspec_opts = ['--backtrace']
14
12
  end
15
13
 
16
14
  task :default do
17
- if ENV['DB'] =~ /mongodb/
18
- Rake::Task["mongoid"].invoke
19
- else
20
- Rake::Task["spec"].invoke
21
- end
15
+ Rake::Task["spec"].invoke
22
16
  end
23
17
 
24
18
  desc "Open an irb session with Ransack and the sample data used in specs"
25
19
  task :console do
26
- require 'irb'
27
- require 'irb/completion'
28
- require 'console'
29
- ARGV.clear
30
- IRB.start
31
- end
32
-
33
- desc "Open an irb session with Ransack, Mongoid and the sample data used in specs"
34
- task :mongoid_console do
35
- require 'irb'
36
- require 'irb/completion'
37
20
  require 'pry'
38
- require 'mongoid'
39
- require File.expand_path('../lib/ransack.rb', __FILE__)
40
- require File.expand_path('../spec/mongoid/support/schema.rb', __FILE__)
21
+ require File.expand_path('../spec/console.rb', __FILE__)
41
22
  ARGV.clear
42
23
  Pry.start
43
24
  end
@@ -0,0 +1,24 @@
1
+ module Polyamorous
2
+ module JoinAssociationExtensions
3
+ include SwappingReflectionClass
4
+ def self.prepended(base)
5
+ base.class_eval { attr_reader :join_type }
6
+ end
7
+
8
+ def initialize(reflection, children, polymorphic_class = nil, join_type = Arel::Nodes::InnerJoin)
9
+ @join_type = join_type
10
+ if polymorphic_class && ::ActiveRecord::Base > polymorphic_class
11
+ swapping_reflection_klass(reflection, polymorphic_class) do |reflection|
12
+ super(reflection, children)
13
+ self.reflection.options[:polymorphic] = true
14
+ end
15
+ else
16
+ super(reflection, children)
17
+ end
18
+ end
19
+
20
+ def ==(other)
21
+ base_klass == other.base_klass
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,79 @@
1
+ module Polyamorous
2
+ module JoinDependencyExtensions
3
+ # Replaces ActiveRecord::Associations::JoinDependency#build
4
+ def build(associations, base_klass)
5
+ associations.map do |name, right|
6
+ if name.is_a? Join
7
+ reflection = find_reflection base_klass, name.name
8
+ reflection.check_validity!
9
+ reflection.check_eager_loadable!
10
+
11
+ klass = if reflection.polymorphic?
12
+ name.klass || base_klass
13
+ else
14
+ reflection.klass
15
+ end
16
+ JoinAssociation.new(reflection, build(right, klass), name.klass, name.type)
17
+ else
18
+ reflection = find_reflection base_klass, name
19
+ reflection.check_validity!
20
+ reflection.check_eager_loadable!
21
+
22
+ if reflection.polymorphic?
23
+ raise ActiveRecord::EagerLoadPolymorphicError.new(reflection)
24
+ end
25
+ JoinAssociation.new(reflection, build(right, reflection.klass))
26
+ end
27
+ end
28
+ end
29
+
30
+ def join_constraints(joins_to_add, join_type, alias_tracker)
31
+ @alias_tracker = alias_tracker
32
+
33
+ construct_tables!(join_root)
34
+ joins = make_join_constraints(join_root, join_type)
35
+
36
+ joins.concat joins_to_add.flat_map { |oj|
37
+ construct_tables!(oj.join_root)
38
+ if join_root.match?(oj.join_root) && join_root.table.name == oj.join_root.table.name
39
+ walk join_root, oj.join_root
40
+ else
41
+ make_join_constraints(oj.join_root, join_type)
42
+ end
43
+ }
44
+ end
45
+
46
+ private
47
+ def make_constraints(parent, child, join_type = Arel::Nodes::OuterJoin)
48
+ foreign_table = parent.table
49
+ foreign_klass = parent.base_klass
50
+ join_type = child.join_type || join_type if join_type == Arel::Nodes::InnerJoin
51
+ joins = child.join_constraints(foreign_table, foreign_klass, join_type, alias_tracker)
52
+ joins.concat child.children.flat_map { |c| make_constraints(child, c, join_type) }
53
+ end
54
+
55
+ module ClassMethods
56
+ # Prepended before ActiveRecord::Associations::JoinDependency#walk_tree
57
+ #
58
+ def walk_tree(associations, hash)
59
+ case associations
60
+ when TreeNode
61
+ associations.add_to_tree(hash)
62
+ when Hash
63
+ associations.each do |k, v|
64
+ cache =
65
+ if TreeNode === k
66
+ k.add_to_tree(hash)
67
+ else
68
+ hash[k] ||= {}
69
+ end
70
+ walk_tree(v, cache)
71
+ end
72
+ else
73
+ super(associations, hash)
74
+ end
75
+ end
76
+ end
77
+
78
+ end
79
+ end
@@ -0,0 +1,11 @@
1
+ module Polyamorous
2
+ module ReflectionExtensions
3
+ def join_scope(table, foreign_table, foreign_klass)
4
+ if respond_to?(:polymorphic?) && polymorphic?
5
+ super.where!(foreign_table[foreign_type].eq(klass.name))
6
+ else
7
+ super
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1 @@
1
+ require 'polyamorous/activerecord_5.2_ruby_2/join_association'
@@ -0,0 +1,80 @@
1
+ # active_record_6.0_ruby_2/join_dependency.rb
2
+ module Polyamorous
3
+ module JoinDependencyExtensions
4
+ # Replaces ActiveRecord::Associations::JoinDependency#build
5
+ def build(associations, base_klass)
6
+ associations.map do |name, right|
7
+ if name.is_a? Join
8
+ reflection = find_reflection base_klass, name.name
9
+ reflection.check_validity!
10
+ reflection.check_eager_loadable!
11
+
12
+ klass = if reflection.polymorphic?
13
+ name.klass || base_klass
14
+ else
15
+ reflection.klass
16
+ end
17
+ JoinAssociation.new(reflection, build(right, klass), name.klass, name.type)
18
+ else
19
+ reflection = find_reflection base_klass, name
20
+ reflection.check_validity!
21
+ reflection.check_eager_loadable!
22
+
23
+ if reflection.polymorphic?
24
+ raise ActiveRecord::EagerLoadPolymorphicError.new(reflection)
25
+ end
26
+ JoinAssociation.new(reflection, build(right, reflection.klass))
27
+ end
28
+ end
29
+ end
30
+
31
+ def join_constraints(joins_to_add, alias_tracker)
32
+ @alias_tracker = alias_tracker
33
+
34
+ construct_tables!(join_root)
35
+ joins = make_join_constraints(join_root, join_type)
36
+
37
+ joins.concat joins_to_add.flat_map { |oj|
38
+ construct_tables!(oj.join_root)
39
+ if join_root.match?(oj.join_root) && join_root.table.name == oj.join_root.table.name
40
+ walk join_root, oj.join_root, oj.join_type
41
+ else
42
+ make_join_constraints(oj.join_root, oj.join_type)
43
+ end
44
+ }
45
+ end
46
+
47
+ private
48
+ def make_constraints(parent, child, join_type = Arel::Nodes::OuterJoin)
49
+ foreign_table = parent.table
50
+ foreign_klass = parent.base_klass
51
+ join_type = child.join_type || join_type if join_type == Arel::Nodes::InnerJoin
52
+ joins = child.join_constraints(foreign_table, foreign_klass, join_type, alias_tracker)
53
+ joins.concat child.children.flat_map { |c| make_constraints(child, c, join_type) }
54
+ end
55
+
56
+ module ClassMethods
57
+ # Prepended before ActiveRecord::Associations::JoinDependency#walk_tree
58
+ #
59
+ def walk_tree(associations, hash)
60
+ case associations
61
+ when TreeNode
62
+ associations.add_to_tree(hash)
63
+ when Hash
64
+ associations.each do |k, v|
65
+ cache =
66
+ if TreeNode === k
67
+ k.add_to_tree(hash)
68
+ else
69
+ hash[k] ||= {}
70
+ end
71
+ walk_tree(v, cache)
72
+ end
73
+ else
74
+ super(associations, hash)
75
+ end
76
+ end
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1 @@
1
+ require 'polyamorous/activerecord_5.2_ruby_2/reflection'
@@ -0,0 +1,74 @@
1
+ module Polyamorous
2
+ module JoinAssociationExtensions
3
+ include SwappingReflectionClass
4
+ def self.prepended(base)
5
+ base.class_eval { attr_reader :join_type }
6
+ end
7
+
8
+ def initialize(reflection, children, polymorphic_class = nil, join_type = Arel::Nodes::InnerJoin)
9
+ @join_type = join_type
10
+ if polymorphic_class && ::ActiveRecord::Base > polymorphic_class
11
+ swapping_reflection_klass(reflection, polymorphic_class) do |reflection|
12
+ super(reflection, children)
13
+ self.reflection.options[:polymorphic] = true
14
+ end
15
+ else
16
+ super(reflection, children)
17
+ end
18
+ end
19
+
20
+ # Same as #join_constraints, but instead of constructing tables from the
21
+ # given block, uses the ones passed
22
+ def join_constraints_with_tables(foreign_table, foreign_klass, join_type, alias_tracker, tables)
23
+ joins = []
24
+ chain = []
25
+
26
+ reflection.chain.each.with_index do |reflection, i|
27
+ table = tables[i]
28
+
29
+ @table ||= table
30
+ chain << [reflection, table]
31
+ end
32
+
33
+ # The chain starts with the target table, but we want to end with it here (makes
34
+ # more sense in this context), so we reverse
35
+ chain.reverse_each do |reflection, table|
36
+ klass = reflection.klass
37
+
38
+ join_scope = reflection.join_scope(table, foreign_table, foreign_klass)
39
+
40
+ unless join_scope.references_values.empty?
41
+ join_dependency = join_scope.construct_join_dependency(
42
+ join_scope.eager_load_values | join_scope.includes_values, Arel::Nodes::OuterJoin
43
+ )
44
+ join_scope.joins!(join_dependency)
45
+ end
46
+
47
+ arel = join_scope.arel(alias_tracker.aliases)
48
+ nodes = arel.constraints.first
49
+
50
+ if nodes.is_a?(Arel::Nodes::And)
51
+ others = nodes.children.extract! do |node|
52
+ !Arel.fetch_attribute(node) { |attr| attr.relation.name == table.name }
53
+ end
54
+ end
55
+
56
+ joins << table.create_join(table, table.create_on(nodes), join_type)
57
+
58
+ if others && !others.empty?
59
+ joins.concat arel.join_sources
60
+ append_constraints(joins.last, others)
61
+ end
62
+
63
+ # The current table in this iteration becomes the foreign table in the next
64
+ foreign_table, foreign_klass = table, klass
65
+ end
66
+
67
+ joins
68
+ end
69
+
70
+ def ==(other)
71
+ base_klass == other.base_klass
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,93 @@
1
+ # active_record_6.1_ruby_2/join_dependency.rb
2
+ module Polyamorous
3
+ module JoinDependencyExtensions
4
+ # Replaces ActiveRecord::Associations::JoinDependency#build
5
+ def build(associations, base_klass)
6
+ associations.map do |name, right|
7
+ if name.is_a? Join
8
+ reflection = find_reflection base_klass, name.name
9
+ reflection.check_validity!
10
+ reflection.check_eager_loadable!
11
+
12
+ klass = if reflection.polymorphic?
13
+ name.klass || base_klass
14
+ else
15
+ reflection.klass
16
+ end
17
+ JoinAssociation.new(reflection, build(right, klass), name.klass, name.type)
18
+ else
19
+ reflection = find_reflection base_klass, name
20
+ reflection.check_validity!
21
+ reflection.check_eager_loadable!
22
+
23
+ if reflection.polymorphic?
24
+ raise ActiveRecord::EagerLoadPolymorphicError.new(reflection)
25
+ end
26
+ JoinAssociation.new(reflection, build(right, reflection.klass))
27
+ end
28
+ end
29
+ end
30
+
31
+ def join_constraints(joins_to_add, alias_tracker, references)
32
+ @alias_tracker = alias_tracker
33
+ @joined_tables = {}
34
+ @references = {}
35
+
36
+ references.each do |table_name|
37
+ @references[table_name.to_sym] = table_name if table_name.is_a?(String)
38
+ end
39
+
40
+ joins = make_join_constraints(join_root, join_type)
41
+
42
+ joins.concat joins_to_add.flat_map { |oj|
43
+ if join_root.match?(oj.join_root) && join_root.table.name == oj.join_root.table.name
44
+ walk join_root, oj.join_root, oj.join_type
45
+ else
46
+ make_join_constraints(oj.join_root, oj.join_type)
47
+ end
48
+ }
49
+ end
50
+
51
+ def construct_tables_for_association!(join_root, association)
52
+ tables = table_aliases_for(join_root, association)
53
+ association.table = tables.first
54
+ tables
55
+ end
56
+
57
+ private
58
+
59
+ def table_aliases_for(parent, node)
60
+ node.reflection.chain.map { |reflection|
61
+ alias_tracker.aliased_table_for(reflection.klass.arel_table) do
62
+ root = reflection == node.reflection
63
+ name = reflection.alias_candidate(parent.table_name)
64
+ root ? name : "#{name}_join"
65
+ end
66
+ }
67
+ end
68
+
69
+ module ClassMethods
70
+ # Prepended before ActiveRecord::Associations::JoinDependency#walk_tree
71
+ #
72
+ def walk_tree(associations, hash)
73
+ case associations
74
+ when TreeNode
75
+ associations.add_to_tree(hash)
76
+ when Hash
77
+ associations.each do |k, v|
78
+ cache =
79
+ if TreeNode === k
80
+ k.add_to_tree(hash)
81
+ else
82
+ hash[k] ||= {}
83
+ end
84
+ walk_tree(v, cache)
85
+ end
86
+ else
87
+ super(associations, hash)
88
+ end
89
+ end
90
+ end
91
+
92
+ end
93
+ end
@@ -0,0 +1 @@
1
+ require 'polyamorous/activerecord_6.0_ruby_2/reflection'
@@ -0,0 +1,70 @@
1
+ module Polyamorous
2
+ class Join
3
+ include TreeNode
4
+
5
+ attr_accessor :name
6
+ attr_reader :type, :klass
7
+
8
+ def initialize(name, type = InnerJoin, klass = nil)
9
+ @name = name
10
+ @type = convert_to_arel_join_type(type)
11
+ @klass = convert_to_class(klass) if klass
12
+ end
13
+
14
+ def klass=(klass)
15
+ @klass = convert_to_class(klass) if klass
16
+ end
17
+
18
+ def type=(type)
19
+ @type = convert_to_arel_join_type(type) if type
20
+ end
21
+
22
+ def hash
23
+ [@name, @type, @klass].hash
24
+ end
25
+
26
+ def eql?(other)
27
+ self.class == other.class &&
28
+ self.name == other.name &&
29
+ self.type == other.type &&
30
+ self.klass == other.klass
31
+ end
32
+
33
+ alias :== :eql?
34
+
35
+ def add_to_tree(hash)
36
+ hash[self] ||= {}
37
+ end
38
+
39
+ private
40
+
41
+ def convert_to_arel_join_type(type)
42
+ case type
43
+ when 'inner', :inner
44
+ InnerJoin
45
+ when 'outer', :outer
46
+ OuterJoin
47
+ when Class
48
+ if [InnerJoin, OuterJoin].include? type
49
+ type
50
+ else
51
+ raise ArgumentError, "#{type} cannot be converted to an ARel join type"
52
+ end
53
+ else
54
+ raise ArgumentError, "#{type} cannot be converted to an ARel join type"
55
+ end
56
+ end
57
+
58
+ def convert_to_class(value)
59
+ case value
60
+ when String, Symbol
61
+ Kernel.const_get(value)
62
+ when Class
63
+ value
64
+ else
65
+ raise ArgumentError, "#{value} cannot be converted to a Class"
66
+ end
67
+ end
68
+
69
+ end
70
+ end
@@ -0,0 +1,24 @@
1
+ if defined?(::ActiveRecord)
2
+ module Polyamorous
3
+ InnerJoin = Arel::Nodes::InnerJoin
4
+ OuterJoin = Arel::Nodes::OuterJoin
5
+
6
+ JoinDependency = ::ActiveRecord::Associations::JoinDependency
7
+ JoinAssociation = ::ActiveRecord::Associations::JoinDependency::JoinAssociation
8
+ end
9
+
10
+ require 'polyamorous/tree_node'
11
+ require 'polyamorous/join'
12
+ require 'polyamorous/swapping_reflection_class'
13
+
14
+ ar_version = ::ActiveRecord::VERSION::STRING[0,3]
15
+ %w(join_association join_dependency reflection).each do |file|
16
+ require "polyamorous/activerecord_#{ar_version}_ruby_2/#{file}"
17
+ end
18
+
19
+ ActiveRecord::Reflection::AbstractReflection.send(:prepend, Polyamorous::ReflectionExtensions)
20
+
21
+ Polyamorous::JoinDependency.send(:prepend, Polyamorous::JoinDependencyExtensions)
22
+ Polyamorous::JoinDependency.singleton_class.send(:prepend, Polyamorous::JoinDependencyExtensions::ClassMethods)
23
+ Polyamorous::JoinAssociation.send(:prepend, Polyamorous::JoinAssociationExtensions)
24
+ end
@@ -0,0 +1,11 @@
1
+ module Polyamorous
2
+ module SwappingReflectionClass
3
+ def swapping_reflection_klass(reflection, klass)
4
+ new_reflection = reflection.clone
5
+ new_reflection.instance_variable_set(:@options, reflection.options.clone)
6
+ new_reflection.options.delete(:polymorphic)
7
+ new_reflection.instance_variable_set(:@klass, klass)
8
+ yield new_reflection
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ module Polyamorous
2
+ module TreeNode
3
+ def add_to_tree(hash)
4
+ raise NotImplementedError
5
+ end
6
+ end
7
+ end
@@ -7,25 +7,42 @@ module Ransack
7
7
  alias :search :ransack unless base.respond_to? :search
8
8
  base.class_eval do
9
9
  class_attribute :_ransackers
10
+ class_attribute :_ransack_aliases
10
11
  self._ransackers ||= {}
12
+ self._ransack_aliases ||= {}
11
13
  end
12
14
  end
13
15
 
14
16
  def ransack(params = {}, options = {})
17
+ ActiveSupport::Deprecation.warn("#search is deprecated and will be removed in 2.3, please use #ransack instead") if __callee__ == :search
15
18
  Search.new(self, params, options)
16
19
  end
17
20
 
21
+ def ransack!(params = {}, options = {})
22
+ ransack(params, options.merge(ignore_unknown_conditions: false))
23
+ end
24
+
18
25
  def ransacker(name, opts = {}, &block)
19
26
  self._ransackers = _ransackers.merge name.to_s => Ransacker
20
27
  .new(self, name, opts, &block)
21
28
  end
22
29
 
30
+ def ransack_alias(new_name, old_name)
31
+ self._ransack_aliases = _ransack_aliases.merge new_name.to_s =>
32
+ old_name.to_s
33
+ end
34
+
23
35
  # Ransackable_attributes, by default, returns all column names
24
36
  # and any defined ransackers as an array of strings.
25
37
  # For overriding with a whitelist array of strings.
26
38
  #
27
39
  def ransackable_attributes(auth_object = nil)
28
- column_names + _ransackers.keys
40
+ @ransackable_attributes ||= if Ransack::SUPPORTS_ATTRIBUTE_ALIAS
41
+ column_names + _ransackers.keys + _ransack_aliases.keys +
42
+ attribute_aliases.keys
43
+ else
44
+ column_names + _ransackers.keys + _ransack_aliases.keys
45
+ end
29
46
  end
30
47
 
31
48
  # Ransackable_associations, by default, returns the names
@@ -33,7 +50,7 @@ module Ransack
33
50
  # For overriding with a whitelist array of strings.
34
51
  #
35
52
  def ransackable_associations(auth_object = nil)
36
- reflect_on_all_associations.map { |a| a.name.to_s }
53
+ @ransackable_associations ||= reflect_on_all_associations.map { |a| a.name.to_s }
37
54
  end
38
55
 
39
56
  # Ransortable_attributes, by default, returns the names
@@ -52,6 +69,14 @@ module Ransack
52
69
  []
53
70
  end
54
71
 
72
+ # ransack_scope_skip_sanitize_args, by default, returns an empty array.
73
+ # i.e. use the sanitize_scope_args setting to determin if args should be converted.
74
+ # For overriding with a list of scopes which should be passed the args as-is.
75
+ #
76
+ def ransackable_scopes_skip_sanitize_args
77
+ []
78
+ end
79
+
55
80
  end
56
81
  end
57
82
  end