referrable_joins 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,26 +1,92 @@
1
1
  module ActiveRecord
2
-
2
+
3
+ class Base
4
+ class << self
5
+ delegate :outer_joins, :inner_joins, :to => :scoped
6
+ end
7
+ end
8
+
3
9
  module QueryMethods
4
- def build_joins(relation, joins)
5
- association_joins = []
10
+
11
+ attr_accessor :outer_joins_values, :inner_joins_values
12
+
13
+ def joins(*args)
14
+ relation = clone
15
+
16
+ args.flatten!
17
+ relation.inner_joins_values ||= []
18
+ relation.inner_joins_values += args unless args.blank?
19
+
20
+ relation
21
+ end
22
+ alias_method :inner_joins, :joins
23
+
24
+ def outer_joins(*args)
25
+ relation = clone
26
+
27
+ args.flatten!
28
+ relation.outer_joins_values ||= []
29
+ relation.outer_joins_values += args unless args.blank?
30
+
31
+ relation
32
+ end
33
+
34
+ def build_arel
35
+ arel = table
36
+
37
+ @inner_joins_values||=[]
38
+ @outer_joins_values||=[]
39
+
40
+ arel = build_joins(arel, @inner_joins_values, @outer_joins_values) unless @outer_joins_values.blank? && @inner_joins_values.blank?
41
+
42
+ (@where_values - ['']).uniq.each do |where|
43
+ where = Arel.sql(where) if String === where
44
+ arel = arel.where(Arel::Nodes::Grouping.new(where))
45
+ end
46
+
47
+ arel = arel.having(*@having_values.uniq.reject{|h| h.blank?}) unless @having_values.empty?
48
+
49
+ arel = arel.take(@limit_value) if @limit_value
50
+ arel = arel.skip(@offset_value) if @offset_value
51
+
52
+ arel = arel.group(*@group_values.uniq.reject{|g| g.blank?}) unless @group_values.empty?
53
+
54
+ arel = arel.order(*@order_values.uniq.reject{|o| o.blank?}) unless @order_values.empty?
55
+
56
+ arel = build_select(arel, @select_values.uniq)
57
+
58
+ arel = arel.from(@from_value) if @from_value
59
+ arel = arel.lock(@lock_value) if @lock_value
60
+
61
+ arel
62
+ end
6
63
 
7
- joins = @joins_values.map {|j| j.respond_to?(:strip) ? j.strip : j}.uniq
64
+
65
+ def build_joins(relation, inner_joins, outer_joins)
66
+ inner_association_joins = []
67
+ outer_association_joins = []
68
+
69
+ inner_joins = @inner_joins_values.map {|j| j.respond_to?(:strip) ? j.strip : j}.uniq
70
+ outer_joins = @outer_joins_values.map {|j| j.respond_to?(:strip) ? j.strip : j}.uniq
8
71
 
9
- joins.each do |join|
10
- # MONKEYPATCH Added ReferrableJoin to the array here.
11
- association_joins << join if [Hash, Array, Symbol, ReferrableJoin].include?(join.class) && !array_of_strings?(join)
72
+ inner_joins.each do |join|
73
+ inner_association_joins << join if [Hash, Array, Symbol, ReferrableJoin].include?(join.class) && !array_of_strings?(join)
12
74
  end
13
75
 
14
- stashed_association_joins = joins.grep(ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation)
76
+ outer_joins.each do |join|
77
+ outer_association_joins << join if [Hash, Array, Symbol, ReferrableJoin].include?(join.class) && !array_of_strings?(join)
78
+ end
15
79
 
16
- non_association_joins = (joins - association_joins - stashed_association_joins)
80
+ stashed_association_joins = (inner_joins + outer_joins).grep(ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation)
81
+
82
+ non_association_joins = (outer_joins + inner_joins - outer_association_joins - inner_association_joins - stashed_association_joins)
17
83
  custom_joins = custom_join_sql(*non_association_joins)
18
84
 
19
- join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(@klass, association_joins, custom_joins)
85
+ join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(@klass, inner_association_joins, outer_association_joins, custom_joins)
20
86
 
21
87
  join_dependency.graft(*stashed_association_joins)
22
88
 
23
- @implicit_readonly = true unless association_joins.empty? && stashed_association_joins.empty?
89
+ @implicit_readonly = true unless inner_association_joins.empty? && outer_association_joins.empty? && stashed_association_joins.empty?
24
90
 
25
91
  to_join = []
26
92
 
@@ -28,23 +94,36 @@ module ActiveRecord
28
94
  if (association_relation = association.relation).is_a?(Array)
29
95
  to_join << [association_relation.first, association.join_type, association.association_join.first]
30
96
  to_join << [association_relation.last, association.join_type, association.association_join.last]
31
- else
97
+ else
32
98
  to_join << [association_relation, association.join_type, association.association_join]
33
99
  end
34
100
  end
35
-
101
+
36
102
  to_join.uniq.each do |left, join_type, right|
37
103
  relation = relation.join(left, join_type).on(*right)
38
104
  end
39
105
 
40
106
  relation.join(custom_joins)
41
107
  end
108
+
42
109
  end
43
110
 
44
111
 
45
112
  module Associations
46
113
  module ClassMethods
47
114
  class JoinDependency
115
+
116
+ def initialize(base, inner_associations, outer_associations, joins)
117
+ @joins = [JoinBase.new(base, joins)]
118
+ @associations = {}
119
+ @reflections = []
120
+ @base_records_hash = {}
121
+ @base_records_in_order = []
122
+ @table_aliases = Hash.new { |aliases, table| aliases[table] = 0 }
123
+ @table_aliases[base.table_name] = 1
124
+ build(inner_associations, @joins.first, Arel::InnerJoin)
125
+ build(outer_associations, @joins.first, Arel::OuterJoin)
126
+ end
48
127
 
49
128
  def build(associations, parent = nil, join_type = Arel::InnerJoin)
50
129
  parent ||= @joins.last
@@ -1,3 +1,3 @@
1
1
  module ReferrableJoins
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -3,7 +3,9 @@ class ReferrableJoin
3
3
  attr_reader :association
4
4
  attr_accessor :relation
5
5
 
6
- delegate :[], :to => :relation
6
+ def [](name)
7
+ relation.columns.find { |col| col.name == name }
8
+ end
7
9
 
8
10
  def initialize(table, association)
9
11
  @association = association
metadata CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
+ - 1
8
9
  - 0
9
- - 2
10
- version: 0.0.2
10
+ version: 0.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Burke Libbey