referrable_joins 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,8 @@
1
+ This is sparse. I will write more later once I know it works properly.
2
+
3
+ > source = ReferrableJoin.new(:languages, :source_language)
4
+ > target = ReferrableJoin.new(:languages, :target_language)
5
+ > Translation.joins(source, target).where(source.relation[:id].lt(2)).size
6
+ => 3
7
+ > Translation.joins(source, target).where(target.relation[:id].lt(2)).size
8
+ => 0
@@ -1,108 +1,29 @@
1
- module ActiveRecord
2
-
3
- # MONKEYPATCH This class is entirely new
4
- class ReferrableJoin
5
-
6
- attr_reader :association
7
- attr_accessor :relation
8
-
9
- def initialize(table, association)
10
- @association = association
11
- @relation = Arel::Table.new(table, ActiveRecord::Base)
12
- end
13
-
14
- def mirror_relation(other)
15
- ["engine", "columns", "table_alias"].each do |ivar|
16
- @relation.instance_variable_set("@#{ivar}", other.instance_variable_get("@#{ivar}"))
17
- end
18
- end
19
-
20
- def to_s
21
- @association.to_s
22
- end
23
-
24
- end
25
-
26
- module QueryMethods
27
- def build_joins(relation, joins)
28
- association_joins = []
29
-
30
- joins = @joins_values.map {|j| j.respond_to?(:strip) ? j.strip : j}.uniq
31
-
32
- joins.each do |join|
33
- # MONKEYPATCH Added ActiveRecord::ReferrableJoin to the array here.
34
- association_joins << join if [Hash, Array, Symbol, ActiveRecord::ReferrableJoin].include?(join.class) && !array_of_strings?(join)
35
- end
36
-
37
- stashed_association_joins = joins.grep(ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation)
38
-
39
- non_association_joins = (joins - association_joins - stashed_association_joins)
40
- custom_joins = custom_join_sql(*non_association_joins)
41
-
42
- join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(@klass, association_joins, custom_joins)
1
+ class ReferrableJoin
43
2
 
44
- join_dependency.graft(*stashed_association_joins)
3
+ attr_reader :association
4
+ attr_accessor :relation
45
5
 
46
- @implicit_readonly = true unless association_joins.empty? && stashed_association_joins.empty?
47
-
48
- to_join = []
49
-
50
- join_dependency.join_associations.each do |association|
51
- if (association_relation = association.relation).is_a?(Array)
52
- to_join << [association_relation.first, association.join_type, association.association_join.first]
53
- to_join << [association_relation.last, association.join_type, association.association_join.last]
54
- else
55
- to_join << [association_relation, association.join_type, association.association_join]
56
- end
57
- end
58
-
59
- to_join.uniq.each do |left, join_type, right|
60
- relation = relation.join(left, join_type).on(*right)
61
- end
62
-
63
- relation.join(custom_joins)
64
- end
65
- end
6
+ delegate :[], :to => :relation
66
7
 
8
+ def initialize(table, association)
9
+ @association = association
10
+ @relation = Arel::Table.new(table, ActiveRecord::Base)
11
+ end
67
12
 
68
- module Associations
69
- module ClassMethods
70
- class JoinDependency
71
-
72
- def build(associations, parent = nil, join_type = Arel::InnerJoin)
73
- parent ||= @joins.last
74
- case associations
75
- # MONKEYPATCH Added ActiveRecord::ReferrableJoin here
76
- when Symbol, String, ActiveRecord::ReferrableJoin
77
- reflection = parent.reflections[associations.to_s.intern] or
78
- raise ConfigurationError, "Association named '#{ associations }' was not found; perhaps you misspelled it\?"
79
- unless join_association = find_join_association(reflection, parent)
80
- @reflections << reflection
81
- join_association = build_join_association(reflection, parent)
82
- # <MONKEYPATCH added this conditional
83
- if associations.kind_of?(ActiveRecord::ReferrableJoin)
84
- associations.mirror_relation(join_association.relation)
85
- end
86
- # >MONKEYPATCH
87
- join_association.join_type = join_type
88
- @joins << join_association
89
- cache_joined_association(join_association)
90
- end
91
- join_association
92
- when Array
93
- associations.each do |association|
94
- build(association, parent, join_type)
95
- end
96
- when Hash
97
- associations.keys.sort{|a,b|a.to_s<=>b.to_s}.each do |name|
98
- join_association = build(name, parent, join_type)
99
- build(associations[name], join_association, join_type)
100
- end
101
- else
102
- raise ConfigurationError, associations.inspect
103
- end
104
- end
105
- end
13
+ def mirror_relation(other)
14
+ ["engine", "columns", "table_alias"].each do |ivar|
15
+ @relation.instance_variable_set("@#{ivar}", other.instance_variable_get("@#{ivar}"))
106
16
  end
107
17
  end
18
+
19
+ def to_s
20
+ @association.to_s
21
+ end
22
+
108
23
  end
24
+
25
+ path = File.join(File.dirname(__FILE__), 'referrable_joins')
26
+ $:.unshift(path) unless $:.include?(path)
27
+
28
+ require 'referrable_joins/active_record_hacks'
29
+
@@ -0,0 +1,85 @@
1
+ module ActiveRecord
2
+
3
+ module QueryMethods
4
+ def build_joins(relation, joins)
5
+ association_joins = []
6
+
7
+ joins = @joins_values.map {|j| j.respond_to?(:strip) ? j.strip : j}.uniq
8
+
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)
12
+ end
13
+
14
+ stashed_association_joins = joins.grep(ActiveRecord::Associations::ClassMethods::JoinDependency::JoinAssociation)
15
+
16
+ non_association_joins = (joins - association_joins - stashed_association_joins)
17
+ custom_joins = custom_join_sql(*non_association_joins)
18
+
19
+ join_dependency = ActiveRecord::Associations::ClassMethods::JoinDependency.new(@klass, association_joins, custom_joins)
20
+
21
+ join_dependency.graft(*stashed_association_joins)
22
+
23
+ @implicit_readonly = true unless association_joins.empty? && stashed_association_joins.empty?
24
+
25
+ to_join = []
26
+
27
+ join_dependency.join_associations.each do |association|
28
+ if (association_relation = association.relation).is_a?(Array)
29
+ to_join << [association_relation.first, association.join_type, association.association_join.first]
30
+ to_join << [association_relation.last, association.join_type, association.association_join.last]
31
+ else
32
+ to_join << [association_relation, association.join_type, association.association_join]
33
+ end
34
+ end
35
+
36
+ to_join.uniq.each do |left, join_type, right|
37
+ relation = relation.join(left, join_type).on(*right)
38
+ end
39
+
40
+ relation.join(custom_joins)
41
+ end
42
+ end
43
+
44
+
45
+ module Associations
46
+ module ClassMethods
47
+ class JoinDependency
48
+
49
+ def build(associations, parent = nil, join_type = Arel::InnerJoin)
50
+ parent ||= @joins.last
51
+ case associations
52
+ # MONKEYPATCH Added ReferrableJoin here
53
+ when Symbol, String, ReferrableJoin
54
+ reflection = parent.reflections[associations.to_s.intern] or
55
+ raise ConfigurationError, "Association named '#{ associations }' was not found; perhaps you misspelled it\?"
56
+ unless join_association = find_join_association(reflection, parent)
57
+ @reflections << reflection
58
+ join_association = build_join_association(reflection, parent)
59
+ # <MONKEYPATCH added this conditional
60
+ if associations.kind_of?(ReferrableJoin)
61
+ associations.mirror_relation(join_association.relation)
62
+ end
63
+ # >MONKEYPATCH
64
+ join_association.join_type = join_type
65
+ @joins << join_association
66
+ cache_joined_association(join_association)
67
+ end
68
+ join_association
69
+ when Array
70
+ associations.each do |association|
71
+ build(association, parent, join_type)
72
+ end
73
+ when Hash
74
+ associations.keys.sort{|a,b|a.to_s<=>b.to_s}.each do |name|
75
+ join_association = build(name, parent, join_type)
76
+ build(associations[name], join_association, join_type)
77
+ end
78
+ else
79
+ raise ConfigurationError, associations.inspect
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -1,3 +1,3 @@
1
1
  module ReferrableJoins
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: referrable_joins
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Burke Libbey
@@ -31,8 +31,10 @@ extra_rdoc_files: []
31
31
  files:
32
32
  - .gitignore
33
33
  - Gemfile
34
+ - README.rdoc
34
35
  - Rakefile
35
36
  - lib/referrable_joins.rb
37
+ - lib/referrable_joins/active_record_hacks.rb
36
38
  - lib/referrable_joins/version.rb
37
39
  - referrable_joins.gemspec
38
40
  has_rdoc: true