ransack 1.8.8 → 1.8.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +9 -1
  3. data/CHANGELOG.md +4 -0
  4. data/Gemfile +3 -6
  5. data/README.md +37 -0
  6. data/lib/polyamorous.rb +55 -0
  7. data/lib/polyamorous/activerecord_3_and_4.0_ruby_1.9/join_association.rb +76 -0
  8. data/lib/polyamorous/activerecord_3_and_4.0_ruby_1.9/join_dependency.rb +96 -0
  9. data/lib/polyamorous/activerecord_4.1_ruby_1.9/join_association.rb +2 -0
  10. data/lib/polyamorous/activerecord_4.1_ruby_1.9/join_dependency.rb +4 -0
  11. data/lib/polyamorous/activerecord_4.1_ruby_2/join_association.rb +2 -0
  12. data/lib/polyamorous/activerecord_4.1_ruby_2/join_dependency.rb +3 -0
  13. data/lib/polyamorous/activerecord_4.1_ruby_2/make_polyamorous_inner_joins.rb +14 -0
  14. data/lib/polyamorous/activerecord_4.2_ruby_1.9/join_association.rb +46 -0
  15. data/lib/polyamorous/activerecord_4.2_ruby_1.9/join_dependency.rb +87 -0
  16. data/lib/polyamorous/activerecord_4.2_ruby_2/join_association.rb +2 -0
  17. data/lib/polyamorous/activerecord_4.2_ruby_2/join_dependency.rb +24 -0
  18. data/lib/polyamorous/activerecord_5.0_ruby_2/join_association.rb +2 -0
  19. data/lib/polyamorous/activerecord_5.0_ruby_2/join_dependency.rb +2 -0
  20. data/lib/polyamorous/activerecord_5.1_ruby_2/join_association.rb +39 -0
  21. data/lib/polyamorous/activerecord_5.1_ruby_2/join_dependency.rb +130 -0
  22. data/lib/polyamorous/activerecord_5.2.0_ruby_2/join_association.rb +39 -0
  23. data/lib/polyamorous/activerecord_5.2.0_ruby_2/join_dependency.rb +131 -0
  24. data/lib/polyamorous/join.rb +70 -0
  25. data/lib/polyamorous/swapping_reflection_class.rb +11 -0
  26. data/lib/polyamorous/tree_node.rb +7 -0
  27. data/lib/ransack/adapters/active_record/3.0/compat.rb +1 -7
  28. data/lib/ransack/adapters/mongoid/ransack/nodes/condition.rb +3 -8
  29. data/lib/ransack/adapters/mongoid/ransack/visitor.rb +1 -7
  30. data/lib/ransack/helpers/form_builder.rb +14 -8
  31. data/lib/ransack/locale/az.yml +70 -0
  32. data/lib/ransack/nodes/grouping.rb +1 -5
  33. data/lib/ransack/version.rb +1 -1
  34. data/lib/ransack/visitor.rb +1 -7
  35. data/ransack.gemspec +3 -5
  36. data/spec/helpers/polyamorous_helper.rb +26 -0
  37. data/spec/ransack/join_association_spec.rb +54 -0
  38. data/spec/ransack/join_dependency_spec.rb +102 -0
  39. data/spec/ransack/join_spec.rb +19 -0
  40. data/spec/spec_helper.rb +1 -0
  41. metadata +51 -17
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f61f4b16a29defa380a26e7c29e3470bb61eb98fee71fb2b506b1b7c377f4995
4
- data.tar.gz: a08063d09eae00edf1f62dfdcb9df19db195fded6d951a0ddb6ff0dd63885095
3
+ metadata.gz: 07c532ea4c1ef918e082ef7877a6fe08fb1bb881860ab28223c3c88da1143883
4
+ data.tar.gz: 6313bf0d848b95b5eb4d6b653c19dbc88a119da2e5d4979b6fcc2ee9a466d00b
5
5
  SHA512:
6
- metadata.gz: 7075b5593e9931a4f5df153e04e2069dbb3b7e65f6463941b5dcfed0abfe6c5eba685b6db246755a98c8268e412d8088855495d14badcb75630c9c9eec86bb81
7
- data.tar.gz: 5243186d40445ea7e1087cf1e655139718eca9089b3de1a52780b4aee71a200f7ac241d27c93821703bbe17872f05e740f12669be8cf129d3f1869967f04e2e2
6
+ metadata.gz: 7e3a42c855d5e1918ed5dfb71e80d236cd5ac8b8e7b9a46d42d0b181e68ac1a6518a9f61f21f844175db2dba97dd66117a356e8a6feba1a8779f6eedc0cb13dc
7
+ data.tar.gz: b8d4bb5978ca13683932922a1ac80a619d2890f871ed56f11743e0aba863a229af33eb7ddf617650fb04fab7548c55703d73ddd77c9ef72fa6a5c34801d73c74
@@ -11,6 +11,10 @@ env:
11
11
  - RAILS=5-2-stable DB=mysql
12
12
  - RAILS=5-2-stable DB=postgres
13
13
 
14
+ - RAILS=v5.2.0 DB=sqlite3
15
+ - RAILS=v5.2.0 DB=mysql
16
+ - RAILS=v5.2.0 DB=postgres
17
+
14
18
  - RAILS=5-0-stable DB=sqlite3
15
19
  - RAILS=5-0-stable DB=mysql
16
20
  - RAILS=5-0-stable DB=postgres
@@ -18,7 +22,11 @@ env:
18
22
  - RAILS=4-2-stable DB=sqlite3
19
23
  - RAILS=4-2-stable DB=mysql
20
24
  - RAILS=4-2-stable DB=postgres
21
-
25
+ matrix:
26
+ allow_failures:
27
+ - env: RAILS=5-2-stable DB=sqlite3
28
+ - env: RAILS=5-2-stable DB=mysql
29
+ - env: RAILS=5-2-stable DB=postgres
22
30
  before_script:
23
31
  - mysql -e 'create database ransack collate utf8_general_ci;'
24
32
  - mysql -e 'use ransack;show variables like "%character%";show variables like "%collation%";'
@@ -1,5 +1,9 @@
1
1
  # Change Log
2
2
 
3
+ ## Version 1.8.9 - 2018-08-09
4
+
5
+ * Locked Active Record compatibiity at 5.1.0
6
+
3
7
  ## Version 1.8.8 - 2018-03-16
4
8
  * Fix multiple database support
5
9
  PR [#893](https://github.com/activerecord-hackery/ransack/pull/893)
data/Gemfile CHANGED
@@ -5,12 +5,6 @@ gem 'rake'
5
5
 
6
6
  rails = ENV['RAILS'] || '5-0-stable'
7
7
 
8
- if rails == 'master'
9
- gem 'polyamorous', github: 'activerecord-hackery/polyamorous'
10
- else
11
- gem 'polyamorous', '~> 1.3'
12
- end
13
-
14
8
  gem 'pry'
15
9
 
16
10
  # Provide timezone information on Windows
@@ -28,6 +22,9 @@ when /^v/ # A tagged version
28
22
  gem 'activerecord', require: false
29
23
  gem 'actionpack'
30
24
  end
25
+ if rails == 'v5.2.0'
26
+ gem 'mysql2', '~> 0.4.4'
27
+ end
31
28
  else
32
29
  git 'git://github.com/rails/rails.git', :branch => rails do
33
30
  gem 'activesupport'
data/README.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Ransack
2
2
 
3
+ ### Maintainer Wanted
4
+
5
+ A note from [Sean](https://github.com/seanfcarroll).
6
+ Ransack is a fantastic gem, and a key part of many Rails projects. It is also a core component of [ActiveAdmin](https://github.com/activeadmin/activeadmin) and generally a great way to add fairly complex search and filtering without having to resort to external services, such as Elasticsearch.
7
+
8
+ In my humble opinion, Ransack can be much more, if it does a bit less. What I mean is that the API vector of Ransack is quite large, and really has been issue-driven. There are complications with Polymorphic relations, complex joins and MongoDB. It's not clear sometimes if there is a bug or not.
9
+
10
+ I was hoping to lead Ransack to version 2.0, and in my opinion this would have included:
11
+
12
+ - Absorbing Polyamorous
13
+ - Splitting MongoDB support into a seperate gem
14
+ - Dropping support for older Rails versions; strictly follow the [Rails support policy](http://guides.rubyonrails.org/maintenance_policy.html). This is important as the codebase is littered with code for de-supported Rails versions
15
+ - Add a generator to build in Ransack with a scaffold
16
+ - Generate tests for Ransack-enabled applications
17
+ - Update the Wiki / docs with lots of examples of 'how-to', questions are the majority of issues on Ransack
18
+ - Increase supported translations
19
+
20
+ Unfortunately I am quite occupied at present with several projects, including [crowdAI](https://github.com/crowdAI/crowdai), and I will need to step down as a maintainer. I have also posted it [here](https://github.com/pickhardt/maintainers-wanted).
21
+
22
+ If you want to step up, please contact me on gmail as **sfcarroll**
23
+
24
+
25
+
3
26
  [![Build Status](https://travis-ci.org/activerecord-hackery/ransack.svg)](https://travis-ci.org/activerecord-hackery/ransack)
4
27
  [![Gem Version](https://badge.fury.io/rb/ransack.svg)](http://badge.fury.io/rb/ransack)
5
28
  [![Code Climate](https://codeclimate.com/github/activerecord-hackery/ransack/badges/gpa.svg)](https://codeclimate.com/github/activerecord-hackery/ransack)
@@ -513,6 +536,20 @@ def index
513
536
  end
514
537
  ```
515
538
 
539
+ Another method to approach this when using Postgresql is to use ActiveRecords's `.includes` in combination with `.group` instead of `distinct: true`.
540
+
541
+ For example:
542
+ ```ruby
543
+ def index
544
+ @q = Person.ransack(params[:q])
545
+ @people = @q.result
546
+ .group('persons.id')
547
+ .includes(:articles)
548
+ .page(params[:page])
549
+ end
550
+
551
+ ```
552
+
516
553
  A final way of last resort is to call `to_a.uniq` on the collection at the end
517
554
  with the caveat that the de-duping is taking place in Ruby instead of in SQL,
518
555
  which is potentially slower and uses more memory, and that it may display
@@ -0,0 +1,55 @@
1
+ if defined?(::ActiveRecord)
2
+ module Polyamorous
3
+ if defined?(Arel::InnerJoin)
4
+ InnerJoin = Arel::InnerJoin
5
+ OuterJoin = Arel::OuterJoin
6
+ else
7
+ InnerJoin = Arel::Nodes::InnerJoin
8
+ OuterJoin = Arel::Nodes::OuterJoin
9
+ end
10
+
11
+ if defined?(::ActiveRecord::Associations::JoinDependency)
12
+ JoinDependency = ::ActiveRecord::Associations::JoinDependency
13
+ JoinAssociation = ::ActiveRecord::Associations::JoinDependency::JoinAssociation
14
+ JoinBase = ::ActiveRecord::Associations::JoinDependency::JoinBase
15
+ else
16
+ JoinDependency = ::ActiveRecord::Associations::ClassMethods::JoinDependency
17
+ JoinAssociation = ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation
18
+ JoinBase = ::ActiveRecord::Associations::ClassMethods::JoinDependency::JoinBase
19
+ end
20
+ end
21
+
22
+ require 'polyamorous/tree_node'
23
+ require 'polyamorous/join'
24
+ require 'polyamorous/swapping_reflection_class'
25
+
26
+ ar_version = ::ActiveRecord::VERSION::STRING[0,3]
27
+ ar_version = '3_and_4.0' if ar_version < '4.1'
28
+ ar_version = ::ActiveRecord::VERSION::STRING[0,5] if ar_version == '5.2'
29
+
30
+ method, ruby_version =
31
+ if RUBY_VERSION >= '2.0' && ar_version >= '4.1'
32
+ # Ruby 2; we can use `prepend` to patch Active Record cleanly.
33
+ [:prepend, '2']
34
+ else
35
+ # Ruby 1.9; we must use `alias_method` to patch Active Record.
36
+ [:include, '1.9']
37
+ end
38
+
39
+ %w(join_association join_dependency).each do |file|
40
+ require "polyamorous/activerecord_#{ar_version}_ruby_#{ruby_version}/#{file}"
41
+ end
42
+
43
+ Polyamorous::JoinDependency.send(method, Polyamorous::JoinDependencyExtensions)
44
+ if method == :prepend
45
+ Polyamorous::JoinDependency.singleton_class
46
+ .send(:prepend, Polyamorous::JoinDependencyExtensions::ClassMethods)
47
+ end
48
+ Polyamorous::JoinAssociation.send(method, Polyamorous::JoinAssociationExtensions)
49
+
50
+ Polyamorous::JoinBase.class_eval do
51
+ if method_defined?(:active_record)
52
+ alias_method :base_klass, :active_record
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,76 @@
1
+ # active_record_3_and_4.0_ruby_1.9/join_association.rb
2
+ module Polyamorous
3
+ module JoinAssociationExtensions
4
+ include SwappingReflectionClass
5
+ def self.included(base)
6
+ base.class_eval do
7
+ alias_method_chain :initialize, :polymorphism
8
+ alias_method :equality_without_polymorphism, :==
9
+ alias_method :==, :equality_with_polymorphism
10
+ if base.method_defined?(:active_record)
11
+ alias_method :base_klass, :active_record
12
+ end
13
+
14
+ if ActiveRecord::VERSION::STRING =~ /^3\.0\./
15
+ alias_method_chain :association_join, :polymorphism
16
+ else
17
+ alias_method_chain :build_constraint, :polymorphism
18
+ end
19
+ end
20
+ end
21
+
22
+ def initialize_with_polymorphism(
23
+ reflection, join_dependency, parent = nil, polymorphic_class = nil
24
+ )
25
+ if polymorphic_class && ::ActiveRecord::Base > polymorphic_class
26
+ swapping_reflection_klass(reflection, polymorphic_class) do |reflection|
27
+ initialize_without_polymorphism(reflection, join_dependency, parent)
28
+ self.reflection.options[:polymorphic] = true
29
+ end
30
+ else
31
+ initialize_without_polymorphism(reflection, join_dependency, parent)
32
+ end
33
+ end
34
+
35
+ def equality_with_polymorphism(other)
36
+ equality_without_polymorphism(other) && base_klass == other.base_klass
37
+ end
38
+
39
+ def build_constraint_with_polymorphism(
40
+ reflection, table, key, foreign_table, foreign_key
41
+ )
42
+ if reflection.options[:polymorphic]
43
+ build_constraint_without_polymorphism(
44
+ reflection, table, key, foreign_table, foreign_key
45
+ )
46
+ .and(foreign_table[reflection.foreign_type].eq(reflection.klass.name))
47
+ else
48
+ build_constraint_without_polymorphism(
49
+ reflection, table, key, foreign_table, foreign_key
50
+ )
51
+ end
52
+ end
53
+
54
+ def association_join_with_polymorphism
55
+ return @join if @Join
56
+ @join = association_join_without_polymorphism
57
+ if reflection.macro == :belongs_to && reflection.options[:polymorphic]
58
+ aliased_table = Arel::Table.new(
59
+ table_name,
60
+ as: @aliased_table_name,
61
+ engine: arel_engine,
62
+ columns: klass.columns
63
+ )
64
+ parent_table = Arel::Table.new(
65
+ parent.table_name,
66
+ as: parent.aliased_table_name,
67
+ engine: arel_engine,
68
+ columns: parent.base_klass.columns
69
+ )
70
+ @join << parent_table[reflection.options[:foreign_type]]
71
+ .eq(reflection.klass.name)
72
+ end
73
+ @join
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,96 @@
1
+ # active_record_3_and_4.0_ruby_1.9/join_dependency.rb
2
+ module Polyamorous
3
+ module JoinDependencyExtensions
4
+ def self.included(base)
5
+ base.class_eval do
6
+ alias_method_chain :build, :polymorphism
7
+ alias_method_chain :graft, :polymorphism
8
+ if base.method_defined?(:active_record)
9
+ alias_method :base_klass, :active_record
10
+ end
11
+ end
12
+ end
13
+
14
+ def graft_with_polymorphism(*associations)
15
+ associations.each do |association|
16
+ unless join_associations.detect { |a| association == a }
17
+ if association.reflection.options[:polymorphic]
18
+ build(
19
+ Join.new(
20
+ association.reflection.name,
21
+ association.join_type,
22
+ association.reflection.klass
23
+ ),
24
+ association.find_parent_in(self) || join_base,
25
+ association.join_type
26
+ )
27
+ else
28
+ build(
29
+ association.reflection.name,
30
+ association.find_parent_in(self) || join_base,
31
+ association.join_type
32
+ )
33
+ end
34
+ end
35
+ end
36
+ self
37
+ end
38
+
39
+ if ActiveRecord::VERSION::STRING =~ /^3\.0\./
40
+ def _join_parts
41
+ @joins
42
+ end
43
+ else
44
+ def _join_parts
45
+ @join_parts
46
+ end
47
+ end
48
+
49
+ def build_with_polymorphism(
50
+ associations, parent = nil, join_type = InnerJoin
51
+ )
52
+ case associations
53
+ when Join
54
+ parent ||= _join_parts.last
55
+ reflection = parent.reflections[associations.name] or
56
+ raise ::ActiveRecord::ConfigurationError,
57
+ "Association named '#{associations.name
58
+ }' was not found; perhaps you misspelled it?"
59
+
60
+ unless join_association = find_join_association_respecting_polymorphism(
61
+ reflection, parent, associations.klass
62
+ )
63
+ @reflections << reflection
64
+ join_association = build_join_association_respecting_polymorphism(
65
+ reflection, parent, associations.klass
66
+ )
67
+ join_association.join_type = associations.type
68
+ _join_parts << join_association
69
+ cache_joined_association(join_association)
70
+ end
71
+
72
+ join_association
73
+ else
74
+ build_without_polymorphism(associations, parent, join_type)
75
+ end
76
+ end
77
+
78
+ def find_join_association_respecting_polymorphism(reflection, parent, klass)
79
+ if association = find_join_association(reflection, parent)
80
+ unless reflection.options[:polymorphic]
81
+ association
82
+ else
83
+ association if association.base_klass == klass
84
+ end
85
+ end
86
+ end
87
+
88
+ def build_join_association_respecting_polymorphism(reflection, parent, klass)
89
+ if reflection.options[:polymorphic] && klass
90
+ JoinAssociation.new(reflection, self, parent, klass)
91
+ else
92
+ JoinAssociation.new(reflection, self, parent)
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,2 @@
1
+ # active_record_4.1_ruby_1.9/join_association.rb
2
+ require 'polyamorous/activerecord_4.2_ruby_1.9/join_association'
@@ -0,0 +1,4 @@
1
+ # active_record_4.1_ruby_1.9/join_dependency.rb
2
+ require 'polyamorous/activerecord_4.2_ruby_2/join_dependency'
3
+ require 'polyamorous/activerecord_4.2_ruby_1.9/join_dependency'
4
+ require 'polyamorous/activerecord_4.1_ruby_2/make_polyamorous_inner_joins'
@@ -0,0 +1,2 @@
1
+ # active_record_4.1_ruby_2/join_association.rb
2
+ require 'polyamorous/activerecord_5.0_ruby_2/join_association'
@@ -0,0 +1,3 @@
1
+ # active_record_4.1_ruby_2/join_dependency.rb
2
+ require 'polyamorous/activerecord_4.2_ruby_2/join_dependency'
3
+ require 'polyamorous/activerecord_4.1_ruby_2/make_polyamorous_inner_joins'
@@ -0,0 +1,14 @@
1
+ module Polyamorous
2
+ module JoinDependencyExtensions
3
+ # Replaces ActiveRecord::Associations::JoinDependency#make_inner_joins
4
+ #
5
+ def make_polyamorous_inner_joins(parent, child)
6
+ make_constraints(
7
+ parent, child, child.tables, child.join_type || Arel::Nodes::InnerJoin
8
+ )
9
+ .concat child.children.flat_map { |c|
10
+ make_polyamorous_inner_joins(child, c)
11
+ }
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,46 @@
1
+ # active_record_4.2_ruby_1.9/join_association.rb
2
+ module Polyamorous
3
+ module JoinAssociationExtensions
4
+ include SwappingReflectionClass
5
+ def self.included(base)
6
+ base.class_eval do
7
+ attr_reader :join_type
8
+ alias_method_chain :initialize, :polymorphism
9
+ alias_method_chain :build_constraint, :polymorphism
10
+ end
11
+ end
12
+
13
+ def initialize_with_polymorphism(reflection, children,
14
+ polymorphic_class = nil, join_type = Arel::Nodes::InnerJoin)
15
+ @join_type = join_type
16
+ if polymorphic_class && ::ActiveRecord::Base > polymorphic_class
17
+ swapping_reflection_klass(reflection, polymorphic_class) do |reflection|
18
+ initialize_without_polymorphism(reflection, children)
19
+ self.reflection.options[:polymorphic] = true
20
+ end
21
+ else
22
+ initialize_without_polymorphism(reflection, children)
23
+ end
24
+ end
25
+
26
+ # Reference https://github.com/rails/rails/commit/9b15db51b78028bfecdb85595624de4b838adbd1
27
+ def ==(other)
28
+ base_klass == other.base_klass
29
+ end
30
+
31
+ def build_constraint_with_polymorphism(
32
+ klass, table, key, foreign_table, foreign_key
33
+ )
34
+ if reflection.polymorphic?
35
+ build_constraint_without_polymorphism(
36
+ klass, table, key, foreign_table, foreign_key
37
+ )
38
+ .and(foreign_table[reflection.foreign_type].eq(reflection.klass.name))
39
+ else
40
+ build_constraint_without_polymorphism(
41
+ klass, table, key, foreign_table, foreign_key
42
+ )
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,87 @@
1
+ # active_record_4.2_ruby_1.9/join_dependency.rb
2
+ require 'polyamorous/activerecord_4.2_ruby_2/join_dependency'
3
+
4
+ module Polyamorous
5
+ module JoinDependencyExtensions
6
+ def self.included(base)
7
+ base.extend ClassMethods
8
+ base.class_eval do
9
+ class << self
10
+ alias_method :walk_tree_without_polymorphism, :walk_tree
11
+ alias_method :walk_tree, :walk_tree_with_polymorphism
12
+ end
13
+
14
+ alias_method :build_without_polymorphism, :build
15
+ alias_method :build, :build_with_polymorphism
16
+
17
+ alias_method :join_constraints_without_polymorphism, :join_constraints
18
+ alias_method :join_constraints, :join_constraints_with_polymorphism
19
+ end
20
+ end
21
+
22
+ # Replaces ActiveRecord::Associations::JoinDependency#build
23
+ #
24
+ def build_with_polymorphism(associations, base_klass)
25
+ associations.map do |name, right|
26
+ if name.is_a? Join
27
+ reflection = find_reflection base_klass, name.name
28
+ reflection.check_validity!
29
+ klass = if reflection.polymorphic?
30
+ name.klass || base_klass
31
+ else
32
+ reflection.klass
33
+ end
34
+ JoinAssociation.new(reflection, build(right, klass), name.klass, name.type)
35
+ else
36
+ reflection = find_reflection base_klass, name
37
+ reflection.check_validity!
38
+ if reflection.polymorphic?
39
+ raise ActiveRecord::EagerLoadPolymorphicError.new(reflection)
40
+ end
41
+ JoinAssociation.new reflection, build(right, reflection.klass)
42
+ end
43
+ end
44
+ end
45
+
46
+ # Replaces ActiveRecord::Associations::JoinDependency#join_constraints
47
+ # to call #make_polyamorous_inner_joins instead of #make_inner_joins
48
+ #
49
+ def join_constraints_with_polymorphism(outer_joins)
50
+ joins = join_root.children.flat_map { |child|
51
+ make_polyamorous_inner_joins join_root, child
52
+ }
53
+ joins.concat outer_joins.flat_map { |oj|
54
+ if join_root.match? oj.join_root
55
+ walk(join_root, oj.join_root)
56
+ else
57
+ oj.join_root.children.flat_map { |child|
58
+ make_outer_joins(oj.join_root, child)
59
+ }
60
+ end
61
+ }
62
+ end
63
+
64
+ module ClassMethods
65
+ # Replaces ActiveRecord::Associations::JoinDependency#self.walk_tree
66
+ #
67
+ def walk_tree_with_polymorphism(associations, hash)
68
+ case associations
69
+ when TreeNode
70
+ associations.add_to_tree(hash)
71
+ when Hash
72
+ associations.each do |k, v|
73
+ cache =
74
+ if TreeNode === k
75
+ k.add_to_tree(hash)
76
+ else
77
+ hash[k] ||= {}
78
+ end
79
+ walk_tree(v, cache)
80
+ end
81
+ else
82
+ walk_tree_without_polymorphism(associations, hash)
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end