baby_squeel 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
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