|
1 | 1 | require "active_record"
|
| 2 | +require_relative "like/scope_spawner" |
2 | 3 |
|
3 | 4 | module ActiveRecord
|
4 | 5 | module Like
|
5 | 6 | module WhereChainExtensions
|
6 | 7 | def like(opts, *rest)
|
7 |
| - opts.each do |k,v| |
8 |
| - if v.is_a?(Array) && v.empty? |
9 |
| - opts[k] = '' |
10 |
| - end |
11 |
| - end |
12 |
| - |
13 |
| - chain_node(Arel::Nodes::Matches, opts, *rest) do |nodes| |
14 |
| - nodes.inject { |memo, node| Arel::Nodes::Or.new(memo, node) } |
15 |
| - end |
| 8 | + ActiveRecord::Like::ScopeSpawners::LikeScopeSpawners.spawn(@scope, opts, rest) |
16 | 9 | end
|
17 | 10 |
|
18 | 11 | def not_like(opts, *rest)
|
19 |
| - opts = opts.reject { |_, v| v.is_a?(Array) && v.empty? } |
20 |
| - chain_node(Arel::Nodes::DoesNotMatch, opts, *rest) do |nodes| |
21 |
| - Arel::Nodes::And.new(nodes) |
22 |
| - end |
23 |
| - end |
24 |
| - |
25 |
| - private |
26 |
| - |
27 |
| - def chain_node(node_type, opts, *rest, &block) |
28 |
| - @scope.tap do |s| |
29 |
| - # Assuming `opts` to be `Hash` |
30 |
| - opts.each_pair do |key, value| |
31 |
| - # 1. Build a where clause to generate "predicates" & "binds" |
32 |
| - # 2. Convert "predicates" into the one that matches `node_type` (like/not like) |
33 |
| - # 3. Re-use binding values to create new where clause |
34 |
| - equal_where_clause = if s.respond_to?(:where_clause_factory, true) |
35 |
| - # ActiveRecord 5.0 to 6.0 |
36 |
| - s.send(:where_clause_factory).build({key => value}, rest) |
37 |
| - else |
38 |
| - # ActiveRecord 6.1, maybe higher |
39 |
| - s.send(:build_where_clause, {key => value}, rest) |
40 |
| - end |
41 |
| - equal_where_clause_predicate = equal_where_clause.send(:predicates).first |
42 |
| - |
43 |
| - new_predicate = if equal_where_clause_predicate.right.is_a?(Array) |
44 |
| - nodes = equal_where_clause_predicate.right.map do |expr| |
45 |
| - node_type.new(equal_where_clause_predicate.left, expr) |
46 |
| - end |
47 |
| - Arel::Nodes::Grouping.new block.call(nodes) |
48 |
| - else |
49 |
| - node_type.new(equal_where_clause_predicate.left, equal_where_clause_predicate.right) |
50 |
| - end |
51 |
| - |
52 |
| - # Passing `Arel::Nodes::Node` into `where_clause_factory` |
53 |
| - # Will lose the binding values since 5.1 |
54 |
| - # due to this PR |
55 |
| - # https://github.com/rails/rails/pull/26073 |
56 |
| - new_where_clause = if equal_where_clause.respond_to?(:binds) |
57 |
| - Relation::WhereClause.new([new_predicate], equal_where_clause.binds) |
58 |
| - else |
59 |
| - Relation::WhereClause.new([new_predicate]) |
60 |
| - end |
61 |
| - |
62 |
| - s.where_clause += new_where_clause |
63 |
| - end |
64 |
| - end |
| 12 | + ActiveRecord::Like::ScopeSpawners::NotLikeScopeSpawners.spawn(@scope, opts, rest) |
65 | 13 | end
|
66 | 14 | end
|
67 | 15 | end
|
|
0 commit comments