activerecord-like 7.0.0 → 7.0.1
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 +4 -4
- data/.github/workflows/coverage.yml +66 -0
- data/.github/workflows/tests.yaml +56 -0
- data/Appraisals +4 -1
- data/CHANGELOG.md +36 -0
- data/README.md +14 -7
- data/activerecord-like.gemspec +16 -5
- data/gemfiles/rails_7_0.gemfile +1 -0
- data/gemfiles/rails_7_1.gemfile +8 -0
- data/gemfiles/rails_7_2.gemfile +7 -0
- data/gemfiles/rails_8_0.gemfile +7 -0
- data/lib/active_record/like/scope_spawner.rb +227 -0
- data/lib/active_record/like/version.rb +7 -5
- data/lib/active_record/like.rb +3 -55
- data/test/helper.rb +19 -0
- data/test/integration/like_test.rb +10 -10
- data/test/integration/not_like_test.rb +10 -10
- data/test/unit/like_test.rb +6 -3
- data/test/unit/not_like_test.rb +6 -3
- metadata +62 -14
- data/.travis.yml +0 -22
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '008bc02548b55ab1abdfb2b5309a6b3550d9d53035c537d84fc7ad6898fb9db2'
|
|
4
|
+
data.tar.gz: 751e85650c858261f054dad65480b671bc6922eba3a2d63e0919f45f28eef82b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4b08f0b31952192ad43da9e43fd59d7fe2902c391f1676ba44e4bf10c5d34b71e20c2083d7086f7c5df2ce6c137deb9102b432871cf1efc350b52e5ccea51813
|
|
7
|
+
data.tar.gz: 6acff383cca259d967df98c9e3db82d42ccb5151bd3509a2262bd80b6a53e170447a81ffb8ff72f87b662ec1a120f9661cc27199664e2a40a25f5c9ab9c46101
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
name: Coverage
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- development
|
|
7
|
+
paths-ignore:
|
|
8
|
+
- 'README.md'
|
|
9
|
+
- 'CHANGELOG.md'
|
|
10
|
+
push:
|
|
11
|
+
branches:
|
|
12
|
+
- development
|
|
13
|
+
paths-ignore:
|
|
14
|
+
- 'README.md'
|
|
15
|
+
- 'CHANGELOG.md'
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
coverage:
|
|
19
|
+
name: Coverage
|
|
20
|
+
# Homemade support for [ci skip] no longer needed
|
|
21
|
+
# https://github.blog/changelog/2021-02-08-github-actions-skip-pull-request-and-push-workflows-with-skip-ci/
|
|
22
|
+
# if: "contains(github.event.commits[0].message, '[ci skip]') == false"
|
|
23
|
+
strategy:
|
|
24
|
+
fail-fast: false
|
|
25
|
+
matrix:
|
|
26
|
+
ruby:
|
|
27
|
+
- "3.3"
|
|
28
|
+
gemfile:
|
|
29
|
+
- gemfiles/rails_7_0.gemfile
|
|
30
|
+
- gemfiles/rails_7_1.gemfile
|
|
31
|
+
- gemfiles/rails_7_2.gemfile
|
|
32
|
+
- gemfiles/rails_8_0.gemfile
|
|
33
|
+
env:
|
|
34
|
+
BUNDLE_GEMFILE: ${{ matrix.gemfile }}
|
|
35
|
+
COVERALLS: true
|
|
36
|
+
runs-on: ubuntu-latest
|
|
37
|
+
steps:
|
|
38
|
+
- name: Checkout
|
|
39
|
+
uses: actions/checkout@v4
|
|
40
|
+
|
|
41
|
+
- name: Setup Ruby
|
|
42
|
+
uses: ruby/setup-ruby@v1
|
|
43
|
+
with:
|
|
44
|
+
ruby-version: ${{ matrix.ruby }}
|
|
45
|
+
bundler-cache: true
|
|
46
|
+
|
|
47
|
+
- name: Collect coverage info
|
|
48
|
+
run: bundle exec rake test
|
|
49
|
+
|
|
50
|
+
- name: Coveralls Parallel
|
|
51
|
+
uses: coverallsapp/github-action@master
|
|
52
|
+
continue-on-error: true
|
|
53
|
+
with:
|
|
54
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
55
|
+
flag-name: run-${{ matrix.ruby }}-${{ matrix.gemfile }}
|
|
56
|
+
parallel: true
|
|
57
|
+
|
|
58
|
+
finish:
|
|
59
|
+
needs: coverage
|
|
60
|
+
runs-on: ubuntu-latest
|
|
61
|
+
steps:
|
|
62
|
+
- name: Send to Coveralls
|
|
63
|
+
uses: coverallsapp/github-action@master
|
|
64
|
+
with:
|
|
65
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
66
|
+
parallel-finished: true
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- development
|
|
7
|
+
paths-ignore:
|
|
8
|
+
- 'README.md'
|
|
9
|
+
push:
|
|
10
|
+
branches:
|
|
11
|
+
- development
|
|
12
|
+
paths-ignore:
|
|
13
|
+
- 'README.md'
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
unit_tests:
|
|
17
|
+
name: Unit Tests
|
|
18
|
+
# Homemade support for [ci skip] no longer needed
|
|
19
|
+
# https://github.blog/changelog/2021-02-08-github-actions-skip-pull-request-and-push-workflows-with-skip-ci/
|
|
20
|
+
# if: "contains(github.event.commits[0].message, '[ci skip]') == false"
|
|
21
|
+
strategy:
|
|
22
|
+
fail-fast: false
|
|
23
|
+
matrix:
|
|
24
|
+
ruby:
|
|
25
|
+
- "3.1"
|
|
26
|
+
- "3.2"
|
|
27
|
+
- "3.3"
|
|
28
|
+
gemfile:
|
|
29
|
+
- gemfiles/rails_7_0.gemfile
|
|
30
|
+
- gemfiles/rails_7_1.gemfile
|
|
31
|
+
- gemfiles/rails_7_2.gemfile
|
|
32
|
+
- gemfiles/rails_8_0.gemfile
|
|
33
|
+
allow_failures:
|
|
34
|
+
- false
|
|
35
|
+
exclude:
|
|
36
|
+
- ruby: "3.1"
|
|
37
|
+
gemfile: gemfiles/rails_8_0.gemfile
|
|
38
|
+
include:
|
|
39
|
+
- ruby: ruby-head
|
|
40
|
+
gemfile: gemfiles/rails_8_0.gemfile
|
|
41
|
+
allow_failures: true
|
|
42
|
+
env:
|
|
43
|
+
BUNDLE_GEMFILE: "${{ matrix.gemfile }}"
|
|
44
|
+
ALLOW_FAILURES: "${{ matrix.allow_failures }}"
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}
|
|
47
|
+
steps:
|
|
48
|
+
- name: Checkout
|
|
49
|
+
uses: actions/checkout@v4
|
|
50
|
+
- name: Setup Ruby
|
|
51
|
+
uses: ruby/setup-ruby@v1
|
|
52
|
+
with:
|
|
53
|
+
ruby-version: ${{ matrix.ruby }}
|
|
54
|
+
bundler-cache: true
|
|
55
|
+
- name: Test
|
|
56
|
+
run: bundle exec rake test || $ALLOW_FAILURES
|
data/Appraisals
CHANGED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
All notable changes to this project will be documented in this file.
|
|
3
|
+
This project adheres to [Semantic Versioning](http://semver.org/).
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## [Unreleased]
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- Nothing
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Nothing
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Nothing
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## [7.0.1] - 2024-12-17
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- Support Rails 8.x
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
## 7.0.0 - 2022-01-20
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
- Support Rails 7.x
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
[Unreleased]: https://github.com/PikachuEXE/where_lower/compare/v7.0.1...HEAD
|
|
36
|
+
[7.0.1]: https://github.com/PikachuEXE/where_lower/compare/v7.0.0...v7.0.1
|
data/README.md
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
# ActiveRecord::Like
|
|
2
2
|
|
|
3
|
-
[](https://codeclimate.com/github/ReneB/activerecord-like)
|
|
5
|
-
[](https://gemnasium.com/ReneB/activerecord-like)
|
|
6
|
-
[](http://badge.fury.io/rb/activerecord-like)
|
|
3
|
+
[](https://github.com/PikachuEXE/activerecord-like/actions/workflows/tests.yaml)
|
|
7
4
|
|
|
8
|
-
[activerecord-like
|
|
5
|
+
[](http://badge.fury.io/rb/activerecord-like)
|
|
6
|
+
[](http://badge.fury.io/rb/activerecord-like)
|
|
7
|
+
|
|
8
|
+
[](https://coveralls.io/r/PikachuEXE/activerecord-like)
|
|
9
|
+
[](https://codeclimate.com/github/PikachuEXE/activerecord-like)
|
|
10
|
+
|
|
11
|
+
[activerecord-like on Github](https://github.com/PikachuEXE/activerecord-like)
|
|
9
12
|
|
|
10
13
|
An Active Record Plugin that allows chaining a more DSL-style 'like' or 'not-like' query to an ActiveRecord::Base#where. Requires Rails 5 or higher.
|
|
11
14
|
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
## History and credits
|
|
16
|
+
|
|
17
|
+
This plugin was originally salvaged from the stellar work done by @amatsuda and @claudiob.
|
|
18
|
+
* Most of the code was previously in Active Record master, but was subsequently removed due to, amongst other, scope creep (see discussion [here](https://github.com/rails/rails/commit/8d02afeaee8993bd0fde69687fdd9bf30921e805)).
|
|
19
|
+
* It was updated to ActiveRecord 5 by @PikachuEXE, then to ActiveRecord 5.2 by @robotdana and to ActiveRecord 6.1 by @nrw505.
|
|
20
|
+
* Array parameter handling was added by @rzane - thanks!
|
|
14
21
|
|
|
15
22
|
## Installation
|
|
16
23
|
|
data/activerecord-like.gemspec
CHANGED
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
2
|
require File.expand_path('../lib/active_record/like/version', __FILE__)
|
|
3
3
|
|
|
4
|
+
main_author_name = "PikachuEXE"
|
|
5
|
+
gem_name = "activerecord-like"
|
|
6
|
+
|
|
4
7
|
Gem::Specification.new do |gem|
|
|
5
|
-
gem.name =
|
|
8
|
+
gem.name = gem_name
|
|
6
9
|
gem.version = ActiveRecord::Like::VERSION
|
|
7
|
-
gem.authors = [
|
|
8
|
-
|
|
10
|
+
gem.authors = [
|
|
11
|
+
"René van den Berg",
|
|
12
|
+
main_author_name,
|
|
13
|
+
]
|
|
14
|
+
gem.email = %w[rene.vandenberg@ogd.nl git@pikachuexe.net]
|
|
9
15
|
gem.description = %q{An ActiveRecord plugin providing a higher-level abstraction for SQL 'LIKE' queries}
|
|
10
16
|
gem.summary = %q{ActiveRecord::Like provides ActiveRecord::Base with where.like(attribute: string)-style extensions. This functionality was, at one point, included in Rails-master, but subsequently removed. Since the feature seemed to be in some demand, I thought I'd try my hand at building an ActiveRecord plugin}
|
|
11
|
-
gem.homepage = "http://github.com
|
|
17
|
+
gem.homepage = "http://github.com/#{main_author_name}/#{gem_name}"
|
|
12
18
|
|
|
13
19
|
gem.files = `git ls-files`.split($/)
|
|
14
20
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
15
21
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
16
22
|
gem.require_paths = ["lib"]
|
|
17
23
|
|
|
18
|
-
gem.add_dependency "activerecord", "
|
|
24
|
+
gem.add_dependency "activerecord", ">= 7.0.0", "< 9.0"
|
|
19
25
|
|
|
20
26
|
# Required for Travis build to pass
|
|
21
27
|
gem.add_development_dependency "pg"
|
|
@@ -27,4 +33,9 @@ Gem::Specification.new do |gem|
|
|
|
27
33
|
gem.add_development_dependency "minitest", ">= 3"
|
|
28
34
|
|
|
29
35
|
gem.add_development_dependency "appraisal", "~> 2.0"
|
|
36
|
+
|
|
37
|
+
gem.add_development_dependency "simplecov", ">= 0.22"
|
|
38
|
+
gem.add_development_dependency "simplecov-lcov", ">= 0.8"
|
|
39
|
+
|
|
40
|
+
gem.add_development_dependency "gem-release", ">= 2.0"
|
|
30
41
|
end
|
data/gemfiles/rails_7_0.gemfile
CHANGED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
module ActiveRecord
|
|
2
|
+
module Like
|
|
3
|
+
module ScopeSpawners
|
|
4
|
+
module Shared
|
|
5
|
+
module Rails7AndBelowSpawner
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
def chain_node(node_type, &block)
|
|
9
|
+
@scope.tap do |s|
|
|
10
|
+
# Assuming `opts` to be `Hash`
|
|
11
|
+
opts.each_pair do |key, value|
|
|
12
|
+
# 1. Build a where clause to generate "predicates" & "binds"
|
|
13
|
+
# 2. Convert "predicates" into the one that matches `node_type` (like/not like)
|
|
14
|
+
# 3. Re-use binding values to create new where clause
|
|
15
|
+
equal_where_clause = if s.respond_to?(:where_clause_factory, true)
|
|
16
|
+
# ActiveRecord 5.0 to 6.0
|
|
17
|
+
s.send(:where_clause_factory).build({key => value}, rest)
|
|
18
|
+
else
|
|
19
|
+
# ActiveRecord 6.1, maybe higher
|
|
20
|
+
s.send(:build_where_clause, {key => value}, rest)
|
|
21
|
+
end
|
|
22
|
+
equal_where_clause_predicate = equal_where_clause.send(:predicates).first
|
|
23
|
+
|
|
24
|
+
new_predicate = if equal_where_clause_predicate.right.is_a?(Array)
|
|
25
|
+
nodes = equal_where_clause_predicate.right.map do |expr|
|
|
26
|
+
node_type.new(equal_where_clause_predicate.left, expr)
|
|
27
|
+
end
|
|
28
|
+
Arel::Nodes::Grouping.new block.call(nodes)
|
|
29
|
+
else
|
|
30
|
+
node_type.new(equal_where_clause_predicate.left, equal_where_clause_predicate.right)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Passing `Arel::Nodes::Node` into `where_clause_factory`
|
|
34
|
+
# Will lose the binding values since 5.1
|
|
35
|
+
# due to this PR
|
|
36
|
+
# https://github.com/rails/rails/pull/26073
|
|
37
|
+
new_where_clause = if equal_where_clause.respond_to?(:binds)
|
|
38
|
+
Relation::WhereClause.new([new_predicate], equal_where_clause.binds)
|
|
39
|
+
else
|
|
40
|
+
Relation::WhereClause.new([new_predicate])
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
s.where_clause += new_where_clause
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
private_constant :Shared
|
|
50
|
+
|
|
51
|
+
module LikeScopeSpawners
|
|
52
|
+
# Spawn different scopes based on value
|
|
53
|
+
# Data conversion and query string generation are handled by different spanwer classes
|
|
54
|
+
#
|
|
55
|
+
# @return [ActiveRecord::Relation] Relation or collection proxy or some AR classs
|
|
56
|
+
def self.spawn(*args)
|
|
57
|
+
RAILS_VERSION_TO_SPAWNER_CLASS_MAPPINGS.fetch(ActiveRecord.version.to_s[0..2]).
|
|
58
|
+
spawn(*args)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# :nodoc:
|
|
63
|
+
class AbstractSpawner
|
|
64
|
+
# :nodoc:
|
|
65
|
+
attr_reader :scope, :opts, :rest
|
|
66
|
+
|
|
67
|
+
# Spawn different scopes based on value
|
|
68
|
+
# Just delegates to new though
|
|
69
|
+
#
|
|
70
|
+
# @param args [Array] arguments that are passed to #initialize
|
|
71
|
+
#
|
|
72
|
+
# @see #initialize
|
|
73
|
+
def self.spawn(*args)
|
|
74
|
+
new(*args).spawn
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Assign ivar only
|
|
78
|
+
# Actual operation is in #spawn
|
|
79
|
+
#
|
|
80
|
+
# @param scope [ActiveRecord::Relation]
|
|
81
|
+
# Relation or collection proxy or some AR classes
|
|
82
|
+
# @param opts [Hash]
|
|
83
|
+
# Column value pairs
|
|
84
|
+
# @param rest [Array]
|
|
85
|
+
# Rest of arguments
|
|
86
|
+
#
|
|
87
|
+
# @see #spawn
|
|
88
|
+
def initialize(scope, opts, *rest)
|
|
89
|
+
@scope = scope
|
|
90
|
+
@opts = opts
|
|
91
|
+
@rest = rest
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Spawn different scopes based on value
|
|
95
|
+
# Data conversion and query string generation are handled by different spanwer classes
|
|
96
|
+
#
|
|
97
|
+
# @return [ActiveRecord::Relation] Relation or collection proxy or some AR classs
|
|
98
|
+
def spawn
|
|
99
|
+
raise NotImplementedError
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# :nodoc:
|
|
104
|
+
class Rails71AndBelowSpawner < AbstractSpawner
|
|
105
|
+
include Shared::Rails7AndBelowSpawner
|
|
106
|
+
|
|
107
|
+
# :nodoc:
|
|
108
|
+
def spawn
|
|
109
|
+
opts.each do |k,v|
|
|
110
|
+
if v.is_a?(Array) && v.empty?
|
|
111
|
+
opts[k] = ''
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
chain_node(Arel::Nodes::Matches) do |nodes|
|
|
116
|
+
nodes.inject { |memo, node| Arel::Nodes::Or.new(memo, node) }
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# :nodoc:
|
|
122
|
+
class Rails72Spawner < AbstractSpawner
|
|
123
|
+
include Shared::Rails7AndBelowSpawner
|
|
124
|
+
|
|
125
|
+
# :nodoc:
|
|
126
|
+
def spawn
|
|
127
|
+
opts.each do |k,v|
|
|
128
|
+
if v.is_a?(Array) && v.empty?
|
|
129
|
+
opts[k] = ''
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
chain_node(Arel::Nodes::Matches) do |nodes|
|
|
134
|
+
Arel::Nodes::Or.new(nodes)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
RAILS_VERSION_TO_SPAWNER_CLASS_MAPPINGS = {
|
|
140
|
+
"7.0" => Rails71AndBelowSpawner,
|
|
141
|
+
"7.1" => Rails71AndBelowSpawner,
|
|
142
|
+
"7.2" => Rails72Spawner,
|
|
143
|
+
"8.0" => Rails72Spawner,
|
|
144
|
+
"8.1" => Rails72Spawner,
|
|
145
|
+
"8.2" => Rails72Spawner,
|
|
146
|
+
}.freeze
|
|
147
|
+
private_constant :RAILS_VERSION_TO_SPAWNER_CLASS_MAPPINGS
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
module NotLikeScopeSpawners
|
|
151
|
+
# Spawn different scopes based on value
|
|
152
|
+
# Data conversion and query string generation are handled by different spanwer classes
|
|
153
|
+
#
|
|
154
|
+
# @return [ActiveRecord::Relation] Relation or collection proxy or some AR classs
|
|
155
|
+
def self.spawn(*args)
|
|
156
|
+
RAILS_VERSION_TO_SPAWNER_CLASS_MAPPINGS.fetch(ActiveRecord.version.to_s[0..2]).
|
|
157
|
+
spawn(*args)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# :nodoc:
|
|
161
|
+
class AbstractSpawner
|
|
162
|
+
# :nodoc:
|
|
163
|
+
attr_reader :scope, :opts, :rest
|
|
164
|
+
|
|
165
|
+
# Spawn different scopes based on value
|
|
166
|
+
# Just delegates to new though
|
|
167
|
+
#
|
|
168
|
+
# @param args [Array] arguments that are passed to #initialize
|
|
169
|
+
#
|
|
170
|
+
# @see #initialize
|
|
171
|
+
def self.spawn(*args)
|
|
172
|
+
new(*args).spawn
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Assign ivar only
|
|
176
|
+
# Actual operation is in #spawn
|
|
177
|
+
#
|
|
178
|
+
# @param scope [ActiveRecord::Relation]
|
|
179
|
+
# Relation or collection proxy or some AR classes
|
|
180
|
+
# @param opts [Hash]
|
|
181
|
+
# Column value pairs
|
|
182
|
+
# @param rest [Array]
|
|
183
|
+
# Rest of arguments
|
|
184
|
+
#
|
|
185
|
+
# @see #spawn
|
|
186
|
+
def initialize(scope, opts, *rest)
|
|
187
|
+
@scope = scope
|
|
188
|
+
@opts = opts
|
|
189
|
+
@rest = rest
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
# Spawn different scopes based on value
|
|
193
|
+
# Data conversion and query string generation are handled by different spanwer classes
|
|
194
|
+
#
|
|
195
|
+
# @return [ActiveRecord::Relation] Relation or collection proxy or some AR classs
|
|
196
|
+
def spawn
|
|
197
|
+
raise NotImplementedError
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# :nodoc:
|
|
202
|
+
class Rails71AndBelowSpawner < AbstractSpawner
|
|
203
|
+
include Shared::Rails7AndBelowSpawner
|
|
204
|
+
|
|
205
|
+
# :nodoc:
|
|
206
|
+
def spawn
|
|
207
|
+
@opts = opts.reject { |_, v| v.is_a?(Array) && v.empty? }
|
|
208
|
+
chain_node(Arel::Nodes::DoesNotMatch) do |nodes|
|
|
209
|
+
Arel::Nodes::And.new(nodes)
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
RAILS_VERSION_TO_SPAWNER_CLASS_MAPPINGS = {
|
|
215
|
+
"7.0" => Rails71AndBelowSpawner,
|
|
216
|
+
"7.1" => Rails71AndBelowSpawner,
|
|
217
|
+
"7.2" => Rails71AndBelowSpawner,
|
|
218
|
+
"8.0" => Rails71AndBelowSpawner,
|
|
219
|
+
"8.1" => Rails71AndBelowSpawner,
|
|
220
|
+
"8.2" => Rails71AndBelowSpawner,
|
|
221
|
+
}.freeze
|
|
222
|
+
private_constant :RAILS_VERSION_TO_SPAWNER_CLASS_MAPPINGS
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
end
|
|
227
|
+
end
|
data/lib/active_record/like.rb
CHANGED
|
@@ -1,67 +1,15 @@
|
|
|
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
|
-
|
|
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
|
-
|
|
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
|
data/test/helper.rb
CHANGED
|
@@ -1,4 +1,23 @@
|
|
|
1
1
|
require 'bundler/setup'
|
|
2
|
+
|
|
3
|
+
if ENV["COVERALLS"]
|
|
4
|
+
require "simplecov"
|
|
5
|
+
require "simplecov-lcov"
|
|
6
|
+
|
|
7
|
+
SimpleCov::Formatter::LcovFormatter.config do |c|
|
|
8
|
+
c.report_with_single_file = true
|
|
9
|
+
c.single_report_path = "coverage/lcov.info"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new(
|
|
13
|
+
[SimpleCov::Formatter::HTMLFormatter, SimpleCov::Formatter::LcovFormatter]
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
SimpleCov.start do
|
|
17
|
+
add_filter "test/"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
2
21
|
require 'minitest/autorun'
|
|
3
22
|
require 'minitest/spec'
|
|
4
23
|
require 'active_record/like'
|
|
@@ -12,7 +12,7 @@ describe ActiveRecord::QueryMethods::WhereChain do
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
it "finds records with attributes matching the criteria" do
|
|
15
|
-
Post.where.like(title: '%there?').map(&:id).must_include 2
|
|
15
|
+
_(Post.where.like(title: '%there?').map(&:id)).must_include 2
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
it "is case-insensitive" do
|
|
@@ -21,30 +21,30 @@ describe ActiveRecord::QueryMethods::WhereChain do
|
|
|
21
21
|
lowercase_posts = Post.where.like(title: search_term)
|
|
22
22
|
uppercase_posts = Post.where.like(title: search_term.upcase)
|
|
23
23
|
|
|
24
|
-
lowercase_posts.map(&:id).must_equal(uppercase_posts.map(&:id))
|
|
24
|
+
_(lowercase_posts.map(&:id)).must_equal(uppercase_posts.map(&:id))
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
it "is chainable" do
|
|
28
28
|
Post.where.like(title: '%there?').order(:title).update_all(title: 'some title')
|
|
29
29
|
|
|
30
|
-
Post.find(2).title.must_equal('some title')
|
|
30
|
+
_(Post.find(2).title).must_equal('some title')
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
it "does not find records with attributes not matching the criteria" do
|
|
34
|
-
Post.where.like(title: '%this title is not used anywhere%').map(&:id).wont_include 2
|
|
34
|
+
_(Post.where.like(title: '%this title is not used anywhere%').map(&:id)).wont_include 2
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
describe "array behavior" do
|
|
38
38
|
it "finds records with attributes matching multiple criteria" do
|
|
39
|
-
Post.where.like(title: ['%DSLs%', 'We need some%']).map(&:id).must_equal [1, 2]
|
|
39
|
+
_(Post.where.like(title: ['%DSLs%', 'We need some%']).map(&:id)).must_equal [1, 2]
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
it "finds records with attributes matching one criterion" do
|
|
43
|
-
Post.where.like(title: ['%there?']).map(&:id).must_equal [2]
|
|
43
|
+
_(Post.where.like(title: ['%there?']).map(&:id)).must_equal [2]
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
it "does not find any records with an empty array" do
|
|
47
|
-
Post.where.like(title: []).must_be_empty
|
|
47
|
+
_(Post.where.like(title: [])).must_be_empty
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
50
|
|
|
@@ -57,15 +57,15 @@ describe ActiveRecord::QueryMethods::WhereChain do
|
|
|
57
57
|
# Interpolating input strings into LIKE queries is an all-too-common
|
|
58
58
|
# mistake that is prevented by the syntax this plugin provides
|
|
59
59
|
it "is possible to inject SQL into literal query strings" do
|
|
60
|
-
Post.where("title LIKE '%#{@user_input}%'").count.must_equal(2)
|
|
60
|
+
_(Post.where("title LIKE '%#{@user_input}%'").count).must_equal(2)
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
it "prevents SQL injection" do
|
|
64
|
-
Post.where.like(title: @user_input).count.must_equal(0)
|
|
64
|
+
_(Post.where.like(title: @user_input).count).must_equal(0)
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
it "prevents SQL injection when provided an array" do
|
|
68
|
-
Post.where.like(title: [@user_input]).count.must_equal(0)
|
|
68
|
+
_(Post.where.like(title: [@user_input]).count).must_equal(0)
|
|
69
69
|
end
|
|
70
70
|
end
|
|
71
71
|
end
|
|
@@ -12,7 +12,7 @@ describe ActiveRecord::QueryMethods::WhereChain do
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
it "finds records with attributes not matching the criteria" do
|
|
15
|
-
Post.where.not_like(title: '%there?').map(&:id).wont_include 2
|
|
15
|
+
_(Post.where.not_like(title: '%there?').map(&:id)).wont_include 2
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
it "is case-insensitive" do
|
|
@@ -21,30 +21,30 @@ describe ActiveRecord::QueryMethods::WhereChain do
|
|
|
21
21
|
lowercase_posts = Post.where.not_like(title: search_term)
|
|
22
22
|
uppercase_posts = Post.where.not_like(title: search_term.upcase)
|
|
23
23
|
|
|
24
|
-
lowercase_posts.map(&:id).must_equal(uppercase_posts.map(&:id))
|
|
24
|
+
_(lowercase_posts.map(&:id)).must_equal(uppercase_posts.map(&:id))
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
it "is chainable" do
|
|
28
28
|
Post.where.not_like(title: '%there?').order(:title).update_all(title: 'some title')
|
|
29
29
|
|
|
30
|
-
Post.find(1).title.must_equal('some title')
|
|
30
|
+
_(Post.find(1).title).must_equal('some title')
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
it "does not find records with attributes matching the criteria" do
|
|
34
|
-
Post.where.not_like(title: '%this title is not used anywhere%').map(&:id).must_include 2
|
|
34
|
+
_(Post.where.not_like(title: '%this title is not used anywhere%').map(&:id)).must_include 2
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
describe "array behavior" do
|
|
38
38
|
it "finds records with attributes not matching multiple criteria" do
|
|
39
|
-
Post.where.not_like(title: ['%DSLs%', 'We need some%']).map(&:id).must_be_empty
|
|
39
|
+
_(Post.where.not_like(title: ['%DSLs%', 'We need some%']).map(&:id)).must_be_empty
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
it "finds records with attributes not matching one criterion" do
|
|
43
|
-
Post.where.not_like(title: ['%there?']).map(&:id).must_equal [1]
|
|
43
|
+
_(Post.where.not_like(title: ['%there?']).map(&:id)).must_equal [1]
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
it "finds all records with an empty array" do
|
|
47
|
-
Post.where.not_like(title: []).count.must_equal 2
|
|
47
|
+
_(Post.where.not_like(title: []).count).must_equal 2
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
50
|
|
|
@@ -57,15 +57,15 @@ describe ActiveRecord::QueryMethods::WhereChain do
|
|
|
57
57
|
# Interpolating input strings into LIKE queries is an all-too-common
|
|
58
58
|
# mistake that is prevented by the syntax this plugin provides
|
|
59
59
|
it "is possible to inject SQL into literal query strings" do
|
|
60
|
-
Post.where("title NOT LIKE '%#{@user_input}%'").count.must_equal(2)
|
|
60
|
+
_(Post.where("title NOT LIKE '%#{@user_input}%'").count).must_equal(2)
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
it "prevents SQL injection" do
|
|
64
|
-
Post.where.not_like(title: @user_input).count.must_equal(2)
|
|
64
|
+
_(Post.where.not_like(title: @user_input).count).must_equal(2)
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
it "prevents SQL injection when provided an array" do
|
|
68
|
-
Post.where.not_like(title: [@user_input]).count.must_equal(2)
|
|
68
|
+
_(Post.where.not_like(title: [@user_input]).count).must_equal(2)
|
|
69
69
|
end
|
|
70
70
|
end
|
|
71
71
|
end
|
data/test/unit/like_test.rb
CHANGED
|
@@ -5,7 +5,7 @@ describe ActiveRecord::QueryMethods::WhereChain do
|
|
|
5
5
|
it "creates an Arel Matches node in the relation" do
|
|
6
6
|
relation = Post.where.like(title: '')
|
|
7
7
|
|
|
8
|
-
relation.where_clause.send(:predicates).first.must_be_instance_of(Arel::Nodes::Matches)
|
|
8
|
+
_(relation.where_clause.send(:predicates).first).must_be_instance_of(Arel::Nodes::Matches)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
describe "the Arel Node" do
|
|
@@ -18,19 +18,22 @@ describe ActiveRecord::QueryMethods::WhereChain do
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
it "has the attribute as the left operand" do
|
|
21
|
-
@first_predicate.left.name.must_equal @attribute
|
|
21
|
+
_(@first_predicate.left.name).must_equal @attribute
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
it "has the value as the right operand" do
|
|
25
25
|
# Rails 5.0 & 5.1
|
|
26
26
|
first_bind = if @relation.where_clause.respond_to?(:binds)
|
|
27
27
|
@relation.where_clause.send(:binds).first
|
|
28
|
+
elsif @first_predicate.right.value.is_a?(String)
|
|
29
|
+
# Rails 7.0+
|
|
30
|
+
@first_predicate.right
|
|
28
31
|
else
|
|
29
32
|
# Rails 5.2
|
|
30
33
|
@first_predicate.right.value
|
|
31
34
|
end
|
|
32
35
|
|
|
33
|
-
first_bind.value.must_equal @value
|
|
36
|
+
_(first_bind.value).must_equal @value
|
|
34
37
|
end
|
|
35
38
|
end
|
|
36
39
|
end
|
data/test/unit/not_like_test.rb
CHANGED
|
@@ -5,7 +5,7 @@ describe ActiveRecord::QueryMethods::WhereChain do
|
|
|
5
5
|
it "creates an Arel DoesNotMatch node in the relation" do
|
|
6
6
|
relation = Post.where.not_like(title: '')
|
|
7
7
|
|
|
8
|
-
relation.where_clause.send(:predicates).first.must_be_instance_of(Arel::Nodes::DoesNotMatch)
|
|
8
|
+
_(relation.where_clause.send(:predicates).first).must_be_instance_of(Arel::Nodes::DoesNotMatch)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
describe "the Arel Node" do
|
|
@@ -18,19 +18,22 @@ describe ActiveRecord::QueryMethods::WhereChain do
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
it "has the attribute as the left operand" do
|
|
21
|
-
@first_predicate.left.name.must_equal @attribute
|
|
21
|
+
_(@first_predicate.left.name).must_equal @attribute
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
it "has the value as the right operand" do
|
|
25
25
|
# Rails 5.0 & 5.1
|
|
26
26
|
first_bind = if @relation.where_clause.respond_to?(:binds)
|
|
27
27
|
@relation.where_clause.send(:binds).first
|
|
28
|
+
elsif @first_predicate.right.value.is_a?(String)
|
|
29
|
+
# Rails 7.0+
|
|
30
|
+
@first_predicate.right
|
|
28
31
|
else
|
|
29
32
|
# Rails 5.2
|
|
30
33
|
@first_predicate.right.value
|
|
31
34
|
end
|
|
32
35
|
|
|
33
|
-
first_bind.value.must_equal @value
|
|
36
|
+
_(first_bind.value).must_equal @value
|
|
34
37
|
end
|
|
35
38
|
end
|
|
36
39
|
end
|
metadata
CHANGED
|
@@ -1,35 +1,36 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activerecord-like
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 7.0.
|
|
4
|
+
version: 7.0.1
|
|
5
5
|
platform: ruby
|
|
6
|
+
original_platform: ''
|
|
6
7
|
authors:
|
|
7
8
|
- René van den Berg
|
|
8
|
-
|
|
9
|
+
- PikachuEXE
|
|
9
10
|
bindir: bin
|
|
10
11
|
cert_chain: []
|
|
11
|
-
date:
|
|
12
|
+
date: 2024-12-17 00:00:00.000000000 Z
|
|
12
13
|
dependencies:
|
|
13
14
|
- !ruby/object:Gem::Dependency
|
|
14
15
|
name: activerecord
|
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
|
16
17
|
requirements:
|
|
17
|
-
- - "~>"
|
|
18
|
-
- !ruby/object:Gem::Version
|
|
19
|
-
version: '7.0'
|
|
20
18
|
- - ">="
|
|
21
19
|
- !ruby/object:Gem::Version
|
|
22
20
|
version: 7.0.0
|
|
21
|
+
- - "<"
|
|
22
|
+
- !ruby/object:Gem::Version
|
|
23
|
+
version: '9.0'
|
|
23
24
|
type: :runtime
|
|
24
25
|
prerelease: false
|
|
25
26
|
version_requirements: !ruby/object:Gem::Requirement
|
|
26
27
|
requirements:
|
|
27
|
-
- - "~>"
|
|
28
|
-
- !ruby/object:Gem::Version
|
|
29
|
-
version: '7.0'
|
|
30
28
|
- - ">="
|
|
31
29
|
- !ruby/object:Gem::Version
|
|
32
30
|
version: 7.0.0
|
|
31
|
+
- - "<"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '9.0'
|
|
33
34
|
- !ruby/object:Gem::Dependency
|
|
34
35
|
name: pg
|
|
35
36
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -114,24 +115,73 @@ dependencies:
|
|
|
114
115
|
- - "~>"
|
|
115
116
|
- !ruby/object:Gem::Version
|
|
116
117
|
version: '2.0'
|
|
118
|
+
- !ruby/object:Gem::Dependency
|
|
119
|
+
name: simplecov
|
|
120
|
+
requirement: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - ">="
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '0.22'
|
|
125
|
+
type: :development
|
|
126
|
+
prerelease: false
|
|
127
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0.22'
|
|
132
|
+
- !ruby/object:Gem::Dependency
|
|
133
|
+
name: simplecov-lcov
|
|
134
|
+
requirement: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - ">="
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0.8'
|
|
139
|
+
type: :development
|
|
140
|
+
prerelease: false
|
|
141
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - ">="
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '0.8'
|
|
146
|
+
- !ruby/object:Gem::Dependency
|
|
147
|
+
name: gem-release
|
|
148
|
+
requirement: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - ">="
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '2.0'
|
|
153
|
+
type: :development
|
|
154
|
+
prerelease: false
|
|
155
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
156
|
+
requirements:
|
|
157
|
+
- - ">="
|
|
158
|
+
- !ruby/object:Gem::Version
|
|
159
|
+
version: '2.0'
|
|
117
160
|
description: An ActiveRecord plugin providing a higher-level abstraction for SQL 'LIKE'
|
|
118
161
|
queries
|
|
119
162
|
email:
|
|
120
163
|
- rene.vandenberg@ogd.nl
|
|
164
|
+
- git@pikachuexe.net
|
|
121
165
|
executables: []
|
|
122
166
|
extensions: []
|
|
123
167
|
extra_rdoc_files: []
|
|
124
168
|
files:
|
|
169
|
+
- ".github/workflows/coverage.yml"
|
|
170
|
+
- ".github/workflows/tests.yaml"
|
|
125
171
|
- ".gitignore"
|
|
126
|
-
- ".travis.yml"
|
|
127
172
|
- Appraisals
|
|
173
|
+
- CHANGELOG.md
|
|
128
174
|
- Gemfile
|
|
129
175
|
- LICENSE.txt
|
|
130
176
|
- README.md
|
|
131
177
|
- Rakefile
|
|
132
178
|
- activerecord-like.gemspec
|
|
133
179
|
- gemfiles/rails_7_0.gemfile
|
|
180
|
+
- gemfiles/rails_7_1.gemfile
|
|
181
|
+
- gemfiles/rails_7_2.gemfile
|
|
182
|
+
- gemfiles/rails_8_0.gemfile
|
|
134
183
|
- lib/active_record/like.rb
|
|
184
|
+
- lib/active_record/like/scope_spawner.rb
|
|
135
185
|
- lib/active_record/like/version.rb
|
|
136
186
|
- lib/activerecord-like.rb
|
|
137
187
|
- test/helper.rb
|
|
@@ -139,10 +189,9 @@ files:
|
|
|
139
189
|
- test/integration/not_like_test.rb
|
|
140
190
|
- test/unit/like_test.rb
|
|
141
191
|
- test/unit/not_like_test.rb
|
|
142
|
-
homepage: http://github.com/
|
|
192
|
+
homepage: http://github.com/PikachuEXE/activerecord-like
|
|
143
193
|
licenses: []
|
|
144
194
|
metadata: {}
|
|
145
|
-
post_install_message:
|
|
146
195
|
rdoc_options: []
|
|
147
196
|
require_paths:
|
|
148
197
|
- lib
|
|
@@ -157,8 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
157
206
|
- !ruby/object:Gem::Version
|
|
158
207
|
version: '0'
|
|
159
208
|
requirements: []
|
|
160
|
-
rubygems_version: 3.
|
|
161
|
-
signing_key:
|
|
209
|
+
rubygems_version: 3.6.0
|
|
162
210
|
specification_version: 4
|
|
163
211
|
summary: 'ActiveRecord::Like provides ActiveRecord::Base with where.like(attribute:
|
|
164
212
|
string)-style extensions. This functionality was, at one point, included in Rails-master,
|
data/.travis.yml
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# Send builds to container-based infrastructure
|
|
2
|
-
# http://docs.travis-ci.com/user/workers/container-based-infrastructure/
|
|
3
|
-
sudo: false
|
|
4
|
-
language: ruby
|
|
5
|
-
cache: bundler
|
|
6
|
-
services:
|
|
7
|
-
- postgresql
|
|
8
|
-
- mysql
|
|
9
|
-
rvm:
|
|
10
|
-
- 2.7.5
|
|
11
|
-
- 3.0.3
|
|
12
|
-
- ruby-head
|
|
13
|
-
env:
|
|
14
|
-
- DB=pg
|
|
15
|
-
- DB=sqlite3
|
|
16
|
-
- DB=mysql
|
|
17
|
-
gemfile:
|
|
18
|
-
- gemfiles/rails_7_0.gemfile
|
|
19
|
-
matrix:
|
|
20
|
-
fast_finish: true
|
|
21
|
-
allow_failures:
|
|
22
|
-
- rvm: ruby-head
|