ransack 1.8.10 → 2.0.0
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.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/.travis.yml +12 -3
- data/CHANGELOG.md +29 -5
- data/Gemfile +1 -9
- data/README.md +16 -25
- data/Rakefile +1 -22
- data/lib/polyamorous.rb +5 -18
- data/lib/polyamorous/activerecord_5.1_ruby_2/join_dependency.rb +2 -2
- data/lib/polyamorous/activerecord_5.2.0_ruby_2/join_dependency.rb +2 -2
- data/lib/polyamorous/activerecord_5.2.1_ruby_2/join_association.rb +38 -0
- data/lib/polyamorous/activerecord_5.2.1_ruby_2/join_dependency.rb +75 -0
- data/lib/ransack/adapters/active_record.rb +0 -9
- data/lib/ransack/adapters/active_record/base.rb +8 -0
- data/lib/ransack/adapters/active_record/context.rb +118 -182
- data/lib/ransack/adapters/active_record/ransack/context.rb +1 -8
- data/lib/ransack/adapters/active_record/ransack/translate.rb +1 -5
- data/lib/ransack/constants.rb +1 -1
- data/lib/ransack/context.rb +4 -0
- data/lib/ransack/nodes/value.rb +1 -1
- data/lib/ransack/search.rb +1 -1
- data/lib/ransack/version.rb +1 -1
- data/ransack.gemspec +4 -3
- data/spec/helpers/polyamorous_helper.rb +7 -9
- data/spec/ransack/adapters/active_record/base_spec.rb +35 -0
- data/spec/ransack/adapters/active_record/context_spec.rb +3 -6
- data/spec/ransack/helpers/form_builder_spec.rb +3 -15
- data/spec/ransack/helpers/form_helper_spec.rb +11 -99
- data/spec/ransack/join_association_spec.rb +1 -6
- data/spec/ransack/join_dependency_spec.rb +1 -6
- data/spec/ransack/search_spec.rb +2 -2
- data/spec/support/schema.rb +3 -21
- metadata +10 -83
- data/lib/polyamorous/activerecord_3_and_4.0_ruby_1.9/join_association.rb +0 -76
- data/lib/polyamorous/activerecord_3_and_4.0_ruby_1.9/join_dependency.rb +0 -96
- data/lib/polyamorous/activerecord_4.1_ruby_1.9/join_association.rb +0 -2
- data/lib/polyamorous/activerecord_4.1_ruby_1.9/join_dependency.rb +0 -4
- data/lib/polyamorous/activerecord_4.1_ruby_2/join_association.rb +0 -2
- data/lib/polyamorous/activerecord_4.1_ruby_2/join_dependency.rb +0 -3
- data/lib/polyamorous/activerecord_4.1_ruby_2/make_polyamorous_inner_joins.rb +0 -14
- data/lib/polyamorous/activerecord_4.2_ruby_1.9/join_association.rb +0 -46
- data/lib/polyamorous/activerecord_4.2_ruby_1.9/join_dependency.rb +0 -87
- data/lib/polyamorous/activerecord_4.2_ruby_2/join_association.rb +0 -2
- data/lib/polyamorous/activerecord_4.2_ruby_2/join_dependency.rb +0 -24
- data/lib/ransack/adapters/active_record/3.0/compat.rb +0 -173
- data/lib/ransack/adapters/active_record/3.0/context.rb +0 -203
- data/lib/ransack/adapters/active_record/3.1/context.rb +0 -212
- data/lib/ransack/adapters/active_record/3.2/context.rb +0 -44
- data/lib/ransack/adapters/mongoid.rb +0 -15
- data/lib/ransack/adapters/mongoid/3.2/.gitkeep +0 -0
- data/lib/ransack/adapters/mongoid/attributes/attribute.rb +0 -37
- data/lib/ransack/adapters/mongoid/attributes/order_predications.rb +0 -17
- data/lib/ransack/adapters/mongoid/attributes/predications.rb +0 -141
- data/lib/ransack/adapters/mongoid/base.rb +0 -134
- data/lib/ransack/adapters/mongoid/context.rb +0 -212
- data/lib/ransack/adapters/mongoid/inquiry_hash.rb +0 -23
- data/lib/ransack/adapters/mongoid/ransack/constants.rb +0 -88
- data/lib/ransack/adapters/mongoid/ransack/context.rb +0 -59
- data/lib/ransack/adapters/mongoid/ransack/nodes/condition.rb +0 -22
- data/lib/ransack/adapters/mongoid/ransack/translate.rb +0 -13
- data/lib/ransack/adapters/mongoid/ransack/visitor.rb +0 -18
- data/lib/ransack/adapters/mongoid/table.rb +0 -35
- data/spec/mongoid/adapters/mongoid/base_spec.rb +0 -314
- data/spec/mongoid/adapters/mongoid/context_spec.rb +0 -56
- data/spec/mongoid/configuration_spec.rb +0 -162
- data/spec/mongoid/dependencies_spec.rb +0 -8
- data/spec/mongoid/helpers/ransack_helper.rb +0 -11
- data/spec/mongoid/nodes/condition_spec.rb +0 -49
- data/spec/mongoid/nodes/grouping_spec.rb +0 -13
- data/spec/mongoid/predicate_spec.rb +0 -155
- data/spec/mongoid/search_spec.rb +0 -445
- data/spec/mongoid/support/mongoid.yml +0 -11
- data/spec/mongoid/support/schema.rb +0 -135
- data/spec/mongoid/translate_spec.rb +0 -14
- data/spec/mongoid_spec_helper.rb +0 -63
- data/spec/ransack/dependencies_spec.rb +0 -12
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'ransack/adapters/mongoid/base'
|
2
|
-
::Mongoid::Document.send :include, Ransack::Adapters::Mongoid::Base
|
3
|
-
|
4
|
-
require 'ransack/adapters/mongoid/attributes/attribute'
|
5
|
-
require 'ransack/adapters/mongoid/table'
|
6
|
-
require 'ransack/adapters/mongoid/inquiry_hash'
|
7
|
-
|
8
|
-
case ::Mongoid::VERSION
|
9
|
-
when /^3\.2\./
|
10
|
-
require 'ransack/adapters/mongoid/3.2/context'
|
11
|
-
else
|
12
|
-
require 'ransack/adapters/mongoid/context'
|
13
|
-
end
|
14
|
-
|
15
|
-
Ransack::SUPPORTS_ATTRIBUTE_ALIAS = false
|
File without changes
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'ransack/adapters/mongoid/attributes/predications'
|
2
|
-
require 'ransack/adapters/mongoid/attributes/order_predications'
|
3
|
-
|
4
|
-
module Ransack
|
5
|
-
module Adapters
|
6
|
-
module Mongoid
|
7
|
-
module Attributes
|
8
|
-
class Attribute < Struct.new :relation, :name
|
9
|
-
# include Arel::Expressions
|
10
|
-
# include Arel::Predications
|
11
|
-
# include Arel::AliasPredication
|
12
|
-
# include Arel::OrderPredications
|
13
|
-
# include Arel::Math
|
14
|
-
|
15
|
-
include ::Ransack::Adapters::Mongoid::Attributes::Predications
|
16
|
-
include ::Ransack::Adapters::Mongoid::Attributes::OrderPredications
|
17
|
-
|
18
|
-
###
|
19
|
-
# Create a node for lowering this attribute
|
20
|
-
def lower
|
21
|
-
relation.lower self
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
class String < Attribute; end
|
26
|
-
class Time < Attribute; end
|
27
|
-
class Boolean < Attribute; end
|
28
|
-
class Decimal < Attribute; end
|
29
|
-
class Float < Attribute; end
|
30
|
-
class Integer < Attribute; end
|
31
|
-
class Undefined < Attribute; end
|
32
|
-
end
|
33
|
-
|
34
|
-
Attribute = Attributes::Attribute
|
35
|
-
end # Attributes
|
36
|
-
end
|
37
|
-
end
|
@@ -1,141 +0,0 @@
|
|
1
|
-
module Ransack
|
2
|
-
module Adapters
|
3
|
-
module Mongoid
|
4
|
-
module Attributes
|
5
|
-
module Predications
|
6
|
-
def not_eq(other)
|
7
|
-
{ name => { '$ne' => other } }.to_inquiry
|
8
|
-
end
|
9
|
-
|
10
|
-
def not_eq_any(others)
|
11
|
-
grouping_any :not_eq, others
|
12
|
-
end
|
13
|
-
|
14
|
-
def not_eq_all(others)
|
15
|
-
grouping_all :not_eq, others
|
16
|
-
end
|
17
|
-
|
18
|
-
def eq(other)
|
19
|
-
{ name => other }.to_inquiry
|
20
|
-
end
|
21
|
-
|
22
|
-
def eq_any(others)
|
23
|
-
grouping_any :eq, others
|
24
|
-
end
|
25
|
-
|
26
|
-
def eq_all(others)
|
27
|
-
grouping_all :eq, others
|
28
|
-
end
|
29
|
-
|
30
|
-
def in(other)
|
31
|
-
{ name => { "$in" => other } }.to_inquiry
|
32
|
-
end
|
33
|
-
|
34
|
-
def in_any(others)
|
35
|
-
grouping_any :in, others
|
36
|
-
end
|
37
|
-
|
38
|
-
def in_all(others)
|
39
|
-
grouping_all :in, others
|
40
|
-
end
|
41
|
-
|
42
|
-
def not_in(other)
|
43
|
-
{ "$not" => { name => { "$in" => other } } }.to_inquiry
|
44
|
-
end
|
45
|
-
|
46
|
-
def not_in_any(others)
|
47
|
-
grouping_any :not_in, others
|
48
|
-
end
|
49
|
-
|
50
|
-
def not_in_all(others)
|
51
|
-
grouping_all :not_in, others
|
52
|
-
end
|
53
|
-
|
54
|
-
def matches(other)
|
55
|
-
{ name => /#{other}/i }.to_inquiry
|
56
|
-
end
|
57
|
-
|
58
|
-
def matches_any(others)
|
59
|
-
grouping_any :matches, others
|
60
|
-
end
|
61
|
-
|
62
|
-
def matches_all(others)
|
63
|
-
grouping_all :matches, others
|
64
|
-
end
|
65
|
-
|
66
|
-
def does_not_match(other)
|
67
|
-
{ "$not" => { name => /#{other}/i } }.to_inquiry
|
68
|
-
end
|
69
|
-
|
70
|
-
def does_not_match_any(others)
|
71
|
-
grouping_any :does_not_match, others
|
72
|
-
end
|
73
|
-
|
74
|
-
def does_not_match_all(others)
|
75
|
-
grouping_all :does_not_match, others
|
76
|
-
end
|
77
|
-
|
78
|
-
def gteq(right)
|
79
|
-
{ name => { '$gte' => right } }.to_inquiry
|
80
|
-
end
|
81
|
-
|
82
|
-
def gteq_any(others)
|
83
|
-
grouping_any :gteq, others
|
84
|
-
end
|
85
|
-
|
86
|
-
def gteq_all(others)
|
87
|
-
grouping_all :gteq, others
|
88
|
-
end
|
89
|
-
|
90
|
-
def gt(right)
|
91
|
-
{ name => { '$gt' => right } }.to_inquiry
|
92
|
-
end
|
93
|
-
|
94
|
-
def gt_any(others)
|
95
|
-
grouping_any :gt, others
|
96
|
-
end
|
97
|
-
|
98
|
-
def gt_all(others)
|
99
|
-
grouping_all :gt, others
|
100
|
-
end
|
101
|
-
|
102
|
-
def lt(right)
|
103
|
-
{ name => { '$lt' => right } }.to_inquiry
|
104
|
-
end
|
105
|
-
|
106
|
-
def lt_any(others)
|
107
|
-
grouping_any :lt, others
|
108
|
-
end
|
109
|
-
|
110
|
-
def lt_all(others)
|
111
|
-
grouping_all :lt, others
|
112
|
-
end
|
113
|
-
|
114
|
-
def lteq(right)
|
115
|
-
{ name => { '$lte' => right } }.to_inquiry
|
116
|
-
end
|
117
|
-
|
118
|
-
def lteq_any(others)
|
119
|
-
grouping_any :lteq, others
|
120
|
-
end
|
121
|
-
|
122
|
-
def lteq_all(others)
|
123
|
-
grouping_all :lteq, others
|
124
|
-
end
|
125
|
-
|
126
|
-
private
|
127
|
-
|
128
|
-
def grouping_any(method_id, others)
|
129
|
-
nodes = others.map { |e| send(method_id, e) }
|
130
|
-
{ "$or" => nodes }.to_inquiry
|
131
|
-
end
|
132
|
-
|
133
|
-
def grouping_all(method_id, others)
|
134
|
-
nodes = others.map { |e| send(method_id, e) }
|
135
|
-
{ "$and" => nodes }.to_inquiry
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
@@ -1,134 +0,0 @@
|
|
1
|
-
require 'delegate'
|
2
|
-
|
3
|
-
module Ransack
|
4
|
-
module Adapters
|
5
|
-
module Mongoid
|
6
|
-
module Base
|
7
|
-
|
8
|
-
extend ActiveSupport::Concern
|
9
|
-
|
10
|
-
included do
|
11
|
-
class_attribute :_ransackers
|
12
|
-
class_attribute :_ransack_aliases
|
13
|
-
self._ransackers ||= {}
|
14
|
-
self._ransack_aliases ||= {}
|
15
|
-
end
|
16
|
-
|
17
|
-
class ColumnWrapper < SimpleDelegator
|
18
|
-
def type
|
19
|
-
_super = super
|
20
|
-
case _super
|
21
|
-
when BSON::ObjectId, Object
|
22
|
-
:string
|
23
|
-
else
|
24
|
-
_super.name.underscore.to_sym
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
class Connection
|
30
|
-
def initialize model
|
31
|
-
@model = model
|
32
|
-
end
|
33
|
-
|
34
|
-
def quote_column_name name
|
35
|
-
name
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
module ClassMethods
|
40
|
-
def ransack(params = {}, options = {})
|
41
|
-
params = params.presence || {}
|
42
|
-
Search.new(self, params ? params.delete_if {
|
43
|
-
|k, v| v.blank? && v != false } : params, options)
|
44
|
-
end
|
45
|
-
|
46
|
-
alias_method :search, :ransack
|
47
|
-
|
48
|
-
def ransack_alias(new_name, old_name)
|
49
|
-
self._ransack_aliases = _ransack_aliases.merge new_name.to_s =>
|
50
|
-
old_name.to_s
|
51
|
-
end
|
52
|
-
|
53
|
-
def ransacker(name, opts = {}, &block)
|
54
|
-
self._ransackers = _ransackers.merge name.to_s => Ransacker
|
55
|
-
.new(self, name, opts, &block)
|
56
|
-
end
|
57
|
-
|
58
|
-
def all_ransackable_attributes
|
59
|
-
['id'] + column_names.select { |c| c != '_id' } + _ransackers.keys +
|
60
|
-
_ransack_aliases.keys
|
61
|
-
end
|
62
|
-
|
63
|
-
def ransackable_attributes(auth_object = nil)
|
64
|
-
all_ransackable_attributes
|
65
|
-
end
|
66
|
-
|
67
|
-
def ransortable_attributes(auth_object = nil)
|
68
|
-
# Here so users can overwrite the attributes
|
69
|
-
# that show up in the sort_select
|
70
|
-
ransackable_attributes(auth_object)
|
71
|
-
end
|
72
|
-
|
73
|
-
def ransackable_associations(auth_object = nil)
|
74
|
-
reflect_on_all_associations_all.map { |a| a.name.to_s }
|
75
|
-
end
|
76
|
-
|
77
|
-
def reflect_on_all_associations_all
|
78
|
-
reflect_on_all_associations(
|
79
|
-
:belongs_to, :has_one, :has_many, :embeds_many, :embedded_in
|
80
|
-
)
|
81
|
-
end
|
82
|
-
|
83
|
-
# For overriding with a whitelist of symbols
|
84
|
-
def ransackable_scopes(auth_object = nil)
|
85
|
-
[]
|
86
|
-
end
|
87
|
-
|
88
|
-
# imitating active record
|
89
|
-
|
90
|
-
def joins_values *args
|
91
|
-
[]
|
92
|
-
end
|
93
|
-
|
94
|
-
def custom_join_ast *args
|
95
|
-
[]
|
96
|
-
end
|
97
|
-
|
98
|
-
def first(*args)
|
99
|
-
if args.size == 0
|
100
|
-
super
|
101
|
-
else
|
102
|
-
self.criteria.limit(args.first)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
# def group_by *args, &block
|
107
|
-
# criteria
|
108
|
-
# end
|
109
|
-
|
110
|
-
def columns
|
111
|
-
@columns ||= fields.map(&:second).map{ |c| ColumnWrapper.new(c) }
|
112
|
-
end
|
113
|
-
|
114
|
-
def column_names
|
115
|
-
@column_names ||= fields.map(&:first)
|
116
|
-
end
|
117
|
-
|
118
|
-
def columns_hash
|
119
|
-
columns.index_by(&:name)
|
120
|
-
end
|
121
|
-
|
122
|
-
def table
|
123
|
-
name = ::Ransack::Adapters::Mongoid::Attributes::Attribute.new(
|
124
|
-
self.criteria, :name
|
125
|
-
)
|
126
|
-
{ :name => name }
|
127
|
-
end
|
128
|
-
|
129
|
-
end
|
130
|
-
|
131
|
-
end # Base
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
@@ -1,212 +0,0 @@
|
|
1
|
-
require 'ransack/context'
|
2
|
-
require 'polyamorous'
|
3
|
-
|
4
|
-
module Ransack
|
5
|
-
module Adapters
|
6
|
-
module Mongoid
|
7
|
-
class Context < ::Ransack::Context
|
8
|
-
|
9
|
-
def initialize(object, options = {})
|
10
|
-
super
|
11
|
-
# @arel_visitor = @engine.connection.visitor
|
12
|
-
end
|
13
|
-
|
14
|
-
def relation_for(object)
|
15
|
-
object.all
|
16
|
-
end
|
17
|
-
|
18
|
-
def type_for(attr)
|
19
|
-
return nil unless attr && attr.valid?
|
20
|
-
name = attr.arel_attribute.name.to_s.split('.').last
|
21
|
-
# table = attr.arel_attribute.relation.table_name
|
22
|
-
|
23
|
-
# schema_cache = @engine.connection.schema_cache
|
24
|
-
# raise "No table named #{table} exists" unless schema_cache.table_exists?(table)
|
25
|
-
# schema_cache.columns_hash(table)[name].type
|
26
|
-
|
27
|
-
# when :date
|
28
|
-
# when :datetime, :timestamp, :time
|
29
|
-
# when :boolean
|
30
|
-
# when :integer
|
31
|
-
# when :float
|
32
|
-
# when :decimal
|
33
|
-
# else # :string
|
34
|
-
|
35
|
-
name = '_id' if name == 'id'
|
36
|
-
|
37
|
-
t = object.klass.fields[name].try(:type) || bind_pair_for(attr.name).first.fields[name].type
|
38
|
-
|
39
|
-
t.to_s.demodulize.underscore.to_sym
|
40
|
-
end
|
41
|
-
|
42
|
-
def evaluate(search, opts = {})
|
43
|
-
viz = Visitor.new
|
44
|
-
relation = @object.where(viz.accept(search.base))
|
45
|
-
if search.sorts.any?
|
46
|
-
ary_sorting = viz.accept(search.sorts)
|
47
|
-
sorting = {}
|
48
|
-
ary_sorting.each do |s|
|
49
|
-
sorting.merge! Hash[s.map { |k, d| [k.to_s == 'id' ? '_id' : k, d] }]
|
50
|
-
end
|
51
|
-
relation = relation.order_by(sorting)
|
52
|
-
# relation = relation.except(:order)
|
53
|
-
# .reorder(viz.accept(search.sorts))
|
54
|
-
end
|
55
|
-
# -- mongoid has different distinct method
|
56
|
-
# opts[:distinct] ? relation.distinct : relation
|
57
|
-
relation
|
58
|
-
end
|
59
|
-
|
60
|
-
def attribute_method?(str, klass = @klass)
|
61
|
-
exists = false
|
62
|
-
if ransackable_attribute?(str, klass)
|
63
|
-
exists = true
|
64
|
-
elsif (segments = str.split(Constants::UNDERSCORE)).size > 1
|
65
|
-
remainder = []
|
66
|
-
found_assoc = nil
|
67
|
-
while !found_assoc && remainder.unshift(
|
68
|
-
segments.pop) && segments.size > 0 do
|
69
|
-
assoc, poly_class = unpolymorphize_association(
|
70
|
-
segments.join('_')
|
71
|
-
)
|
72
|
-
if found_assoc = get_association(assoc, klass)
|
73
|
-
exists = attribute_method?(remainder.join('_'),
|
74
|
-
poly_class || found_assoc.klass
|
75
|
-
)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
exists
|
80
|
-
end
|
81
|
-
|
82
|
-
def table_for(parent)
|
83
|
-
# parent.table
|
84
|
-
Ransack::Adapters::Mongoid::Table.new(parent)
|
85
|
-
end
|
86
|
-
|
87
|
-
def klassify(obj)
|
88
|
-
if Class === obj && obj.ancestors.include?(::Mongoid::Document)
|
89
|
-
obj
|
90
|
-
elsif obj.respond_to? :klass
|
91
|
-
obj.klass
|
92
|
-
elsif obj.respond_to? :base_klass
|
93
|
-
obj.base_klass
|
94
|
-
else
|
95
|
-
raise ArgumentError, "Don't know how to klassify #{obj}"
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def lock_association(association)
|
100
|
-
warn "lock_association is not implemented for Ransack mongoid adapter" if $DEBUG
|
101
|
-
end
|
102
|
-
|
103
|
-
def remove_association(association)
|
104
|
-
warn "remove_association is not implemented for Ransack mongoid adapter" if $DEBUG
|
105
|
-
end
|
106
|
-
|
107
|
-
private
|
108
|
-
|
109
|
-
def get_parent_and_attribute_name(str, parent = @base)
|
110
|
-
attr_name = nil
|
111
|
-
|
112
|
-
if ransackable_attribute?(str, klassify(parent))
|
113
|
-
attr_name = str
|
114
|
-
elsif (segments = str.split(Constants::UNDERSCORE)).size > 1
|
115
|
-
remainder = []
|
116
|
-
found_assoc = nil
|
117
|
-
while remainder.unshift(
|
118
|
-
segments.pop) && segments.size > 0 && !found_assoc do
|
119
|
-
assoc, klass = unpolymorphize_association(segments.join('_'))
|
120
|
-
if found_assoc = get_association(assoc, parent)
|
121
|
-
parent, attr_name = get_parent_and_attribute_name(
|
122
|
-
remainder.join('_'), found_assoc.klass
|
123
|
-
)
|
124
|
-
attr_name = "#{segments.join('_')}.#{attr_name}"
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
[parent, attr_name]
|
130
|
-
end
|
131
|
-
|
132
|
-
def get_association(str, parent = @base)
|
133
|
-
klass = klassify parent
|
134
|
-
ransackable_association?(str, klass) &&
|
135
|
-
klass.reflect_on_all_associations_all.detect { |a| a.name.to_s == str }
|
136
|
-
end
|
137
|
-
|
138
|
-
def join_dependency(relation)
|
139
|
-
if relation.respond_to?(:join_dependency) # Polyamorous enables this
|
140
|
-
relation.join_dependency
|
141
|
-
else
|
142
|
-
build_join_dependency(relation)
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
# Checkout active_record/relation/query_methods.rb +build_joins+ for
|
147
|
-
# reference. Lots of duplicated code maybe we can avoid it
|
148
|
-
def build_join_dependency(relation)
|
149
|
-
buckets = relation.joins_values.group_by do |join|
|
150
|
-
case join
|
151
|
-
when String
|
152
|
-
Constants::STRING_JOIN
|
153
|
-
when Hash, Symbol, Array
|
154
|
-
Constants::ASSOCIATION_JOIN
|
155
|
-
when JoinDependency, JoinDependency::JoinAssociation
|
156
|
-
Constants::STASHED_JOIN
|
157
|
-
when Arel::Nodes::Join
|
158
|
-
Constants::JOIN_NODE
|
159
|
-
else
|
160
|
-
raise 'unknown class: %s' % join.class.name
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
association_joins = buckets[Constants::ASSOCIATION_JOIN] || []
|
165
|
-
|
166
|
-
stashed_association_joins = buckets[Constants::STASHED_JOIN] || []
|
167
|
-
|
168
|
-
join_nodes = buckets[Constants::JOIN_NODE] || []
|
169
|
-
|
170
|
-
string_joins = (buckets[Constants::STRING_JOIN] || [])
|
171
|
-
.map { |x| x.strip }
|
172
|
-
.uniq
|
173
|
-
|
174
|
-
join_list = relation.send :custom_join_ast,
|
175
|
-
relation.table.from(relation.table), string_joins
|
176
|
-
|
177
|
-
join_dependency = JoinDependency.new(
|
178
|
-
relation.klass, association_joins, join_list
|
179
|
-
)
|
180
|
-
|
181
|
-
join_nodes.each do |join|
|
182
|
-
join_dependency.alias_tracker.aliases[join.left.name.downcase] = 1
|
183
|
-
end
|
184
|
-
|
185
|
-
join_dependency # ActiveRecord::Associations::JoinDependency
|
186
|
-
end
|
187
|
-
|
188
|
-
# ActiveRecord method
|
189
|
-
def build_or_find_association(name, parent = @base, klass = nil)
|
190
|
-
found_association = @join_dependency.join_associations
|
191
|
-
.detect do |assoc|
|
192
|
-
assoc.reflection.name == name &&
|
193
|
-
assoc.parent == parent &&
|
194
|
-
(!klass || assoc.reflection.klass == klass)
|
195
|
-
end
|
196
|
-
unless found_association
|
197
|
-
@join_dependency.send(
|
198
|
-
:build,
|
199
|
-
Polyamorous::Join.new(name, @join_type, klass),
|
200
|
-
parent
|
201
|
-
)
|
202
|
-
found_association = @join_dependency.join_associations.last
|
203
|
-
# Leverage the stashed association functionality in AR
|
204
|
-
@object = @object.joins(found_association)
|
205
|
-
end
|
206
|
-
found_association
|
207
|
-
end
|
208
|
-
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|