baby_squeel 1.0.1 → 1.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dccc30465ef9e1b82eed32a0e96c17a5a7fc4e45
4
- data.tar.gz: 9a89635d8f91cdd04f6015141de2ab04dda6c224
3
+ metadata.gz: 5af60f5e34fa18ceb9ad797eecadbce54748f62a
4
+ data.tar.gz: d517b61dbeca8309c511f3aff60ca2d180f1c7fa
5
5
  SHA512:
6
- metadata.gz: 7c07d0fdbb62c82a2e24575d31c46c7f2e4f6acb87c637d57204c357e1507e682b89f5d996b69ea69580279d9e0afea0fc22c20d3d720bc945c78bccee6ea397
7
- data.tar.gz: 82203055a8712beed7bef9651f45863d187ca5518dc0012e1d8ef29cb3c4266ceeeca5835f6fded0498c6130de01a44c47d24526ce5a7b9a0e35b65b9d637459
6
+ metadata.gz: 440bd7a2c660302617fd8b67bcc7dfd9cfb919a3f16cb9dac76c23a467a3ad9935b77ed97d4c5847170d16315c19c9dbbed0a4ad4be0fa8f330abadbfd339503
7
+ data.tar.gz: 2693828aa10e64d7f724270d1be14fc47d72d8ab1c93169da703bef43395132ea51c2365b865d149c8b1c965592238d3982cee2b9a2be22370ce10a0a5185ed3
@@ -2,6 +2,13 @@
2
2
 
3
3
  *Nothing yet.*
4
4
 
5
+ ## [1.0.2] - 2017-02-07
6
+ ### Added
7
+ - `BabySqueel::Association` now has `#==` and `#!=`. This is only supported for Rails 5+. Example: `Post.where { author: Author.last }`.
8
+
9
+ ### Fixed
10
+ - Incorrect alias detection caused by not tracking the full path to a join (#37).
11
+
5
12
  ## [1.0.1] - 2016-11-07
6
13
  ### Added
7
14
  - Add DSL#_ for wrapping expressions in Arel::Node::Grouping. Thanks to [@odedniv].
@@ -81,7 +88,8 @@
81
88
  ### Added
82
89
  - Initial support for selects, orders, wheres, and joins.
83
90
 
84
- [Unreleased]: https://github.com/rzane/baby_squeel/compare/v1.0.1...HEAD
91
+ [Unreleased]: https://github.com/rzane/baby_squeel/compare/v1.0.2...HEAD
92
+ [1.0.2]: https://github.com/rzane/baby_squeel/compare/v1.0.1...v1.0.2
85
93
  [1.0.1]: https://github.com/rzane/baby_squeel/compare/v1.0.0...v1.0.1
86
94
  [1.0.0]: https://github.com/rzane/baby_squeel/compare/v0.3.1...v1.0.0
87
95
  [0.3.1]: https://github.com/rzane/baby_squeel/compare/v0.3.0...v0.3.1
@@ -20,6 +20,14 @@ module BabySqueel
20
20
  end
21
21
  end
22
22
 
23
+ def ==(other)
24
+ Nodes.wrap build_where_clause(other).ast
25
+ end
26
+
27
+ def !=(other)
28
+ Nodes.wrap build_where_clause(other).invert.ast
29
+ end
30
+
23
31
  def of(klass)
24
32
  unless _reflection.polymorphic?
25
33
  raise PolymorphicSpecificationError.new(_reflection.name, klass)
@@ -51,8 +59,8 @@ module BabySqueel
51
59
  end
52
60
 
53
61
  # See BabySqueel::Table#find_alias.
54
- def find_alias(association, associations = [])
55
- @parent.find_alias(association, [self, *associations])
62
+ def find_alias(associations = [])
63
+ @parent.find_alias([self, *associations])
56
64
  end
57
65
 
58
66
  # Intelligently constructs Arel nodes. There are three outcomes:
@@ -85,5 +93,31 @@ module BabySqueel
85
93
  @parent._arel([self, *associations])
86
94
  end
87
95
  end
96
+
97
+ private
98
+
99
+ if ActiveRecord::VERSION::MAJOR >= 5
100
+ def build_where_clause(other)
101
+ if valid_where_clause?(other)
102
+ relation = @parent._scope.where(nil)
103
+ factory = relation.send(:where_clause_factory)
104
+ factory.build({ _reflection.name => other }, [])
105
+ else
106
+ raise AssociationComparisonError.new(_reflection.name, other)
107
+ end
108
+ end
109
+ else
110
+ def build_where_clause(_)
111
+ raise AssociationComparisonNotSupportedError.new(_reflection.name)
112
+ end
113
+ end
114
+
115
+ def valid_where_clause?(other)
116
+ if other.respond_to? :all?
117
+ other.all? { |o| valid_where_clause? o }
118
+ else
119
+ other.nil? || other.respond_to?(:model_name)
120
+ end
121
+ end
88
122
  end
89
123
  end
@@ -45,4 +45,20 @@ module BabySqueel
45
45
  super format(MESSAGE, association: association)
46
46
  end
47
47
  end
48
+
49
+ class AssociationComparisonError < StandardError # :nodoc:
50
+ def initialize(name, other)
51
+ super "You can't compare association '#{name}' to #{other}."
52
+ end
53
+ end
54
+
55
+ class AssociationComparisonNotSupportedError < StandardError # :nodoc:
56
+ MESSAGE =
57
+ "Querying association '%{name}' with '==' and '!=' " \
58
+ "is only supported for ActiveRecord >=5."
59
+
60
+ def initialize(name)
61
+ super format(MESSAGE, name: name)
62
+ end
63
+ end
48
64
  end
@@ -16,13 +16,29 @@ module BabySqueel
16
16
  @joins_values += values
17
17
  end
18
18
 
19
- def to_join_dependency
19
+ def join_dependency
20
20
  ::ActiveRecord::Associations::JoinDependency.new(
21
21
  relation.model,
22
22
  association_joins,
23
23
  join_list
24
24
  )
25
25
  end
26
+ delegate :join_root, to: :join_dependency
27
+
28
+ def find_join_association(associations)
29
+ associations.inject(join_root) do |parent, assoc|
30
+ parent.children.find do |join_association|
31
+ join_association.reflection == assoc._reflection
32
+ end
33
+ end
34
+ end
35
+
36
+ # Find the alias of a BabySqueel::Association, by passing
37
+ # a list (in order of chaining) of associations and finding
38
+ # the respective JoinAssociation at each level.
39
+ def find_alias(associations)
40
+ find_join_association(associations).table
41
+ end
26
42
 
27
43
  private
28
44
 
@@ -3,17 +3,13 @@ module BabySqueel
3
3
  # This class allows BabySqueel to slip custom
4
4
  # joins_values into Active Record's JoinDependency
5
5
  class Injector < Array # :nodoc:
6
- def initialize(joins)
7
- @joins = joins
8
- end
9
-
10
6
  # Active Record will call group_by on this object
11
7
  # in ActiveRecord::QueryMethods#build_joins. This
12
8
  # allows BabySqueel::JoinExpressions to be treated
13
9
  # like typical join hashes until Polyamorous can
14
10
  # deal with them.
15
- def group_by(&block)
16
- @joins.group_by do |join|
11
+ def group_by
12
+ super do |join|
17
13
  case join
18
14
  when BabySqueel::JoinExpression
19
15
  :association_join
@@ -1,6 +1,3 @@
1
- require 'baby_squeel/join_dependency/builder'
2
- require 'baby_squeel/join_dependency/finder'
3
-
4
1
  module BabySqueel
5
2
  # This is the thing that gets added to Active Record's joins_values.
6
3
  # By including Polyamorous::TreeNode, when this instance is found when
@@ -19,8 +19,7 @@ module BabySqueel
19
19
 
20
20
  def _arel
21
21
  if @parent.kind_of? BabySqueel::Association
22
- table = @parent.find_alias(@parent)
23
- table ? table[@name] : super
22
+ @parent.find_alias[@name]
24
23
  else
25
24
  super
26
25
  end
@@ -1,4 +1,5 @@
1
1
  require 'baby_squeel/join_expression'
2
+ require 'baby_squeel/join_dependency/builder'
2
3
 
3
4
  module BabySqueel
4
5
  class Table
@@ -63,12 +64,10 @@ module BabySqueel
63
64
  # attributes reference can change (due to aliasing).
64
65
  # This method allows BabySqueel::Nodes::Attribute
65
66
  # instances to find what their alias will be.
66
- def find_alias(association, associations = [])
67
+ def find_alias(associations = [])
67
68
  builder = JoinDependency::Builder.new(_scope.all)
68
- builder.ensure_associated(_arel(associations))
69
-
70
- finder = JoinDependency::Finder.new(builder.to_join_dependency)
71
- finder.find_alias(association._reflection)
69
+ builder.ensure_associated _arel(associations)
70
+ builder.find_alias(associations)
72
71
  end
73
72
 
74
73
  # This method will be invoked by BabySqueel::Nodes::unwrap. When called,
@@ -1,3 +1,3 @@
1
1
  module BabySqueel
2
- VERSION = '1.0.1'.freeze
2
+ VERSION = '1.0.2'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: baby_squeel
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ray Zane
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-11-08 00:00:00.000000000 Z
11
+ date: 2017-02-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -115,7 +115,6 @@ files:
115
115
  - lib/baby_squeel/dsl.rb
116
116
  - lib/baby_squeel/errors.rb
117
117
  - lib/baby_squeel/join_dependency/builder.rb
118
- - lib/baby_squeel/join_dependency/finder.rb
119
118
  - lib/baby_squeel/join_dependency/injector.rb
120
119
  - lib/baby_squeel/join_expression.rb
121
120
  - lib/baby_squeel/nodes.rb
@@ -154,3 +153,4 @@ signing_key:
154
153
  specification_version: 4
155
154
  summary: A tiny squeel implementation without all of the evil.
156
155
  test_files: []
156
+ has_rdoc:
@@ -1,36 +0,0 @@
1
- module BabySqueel
2
- module JoinDependency
3
- class Finder # :nodoc:
4
- attr_reader :join_dependency
5
-
6
- def initialize(join_dependency)
7
- @join_dependency = join_dependency
8
- end
9
-
10
- def find_alias(reflection)
11
- join_association = find_association(reflection)
12
- join_association.tables.first if join_association
13
- end
14
-
15
- private
16
-
17
- def find(&block)
18
- deeply_find(join_dependency.join_root, &block)
19
- end
20
-
21
- def find_association(reflection)
22
- find { |assoc| assoc.reflection == reflection }
23
- end
24
-
25
- def deeply_find(root, &block)
26
- root.children.each do |assoc|
27
- found = assoc if yield assoc
28
- found ||= deeply_find(assoc, &block)
29
- return found if found
30
- end
31
-
32
- nil
33
- end
34
- end
35
- end
36
- end