active_record-union_relation 0.1.0 → 0.2.0
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/dependabot.yml +16 -0
- data/.github/workflows/auto-merge.yml +22 -0
- data/.github/workflows/main.yml +72 -17
- data/CHANGELOG.md +17 -2
- data/CODE_OF_CONDUCT.md +1 -1
- data/Gemfile +5 -1
- data/Gemfile.lock +174 -113
- data/LICENSE +1 -1
- data/README.md +23 -8
- data/Rakefile +14 -5
- data/active_record-union_relation.gemspec +32 -22
- data/gemfiles/mysql/Gemfile +7 -0
- data/gemfiles/mysql/Gemfile.lock +202 -0
- data/gemfiles/postgresql/Gemfile +7 -0
- data/gemfiles/postgresql/Gemfile.lock +202 -0
- data/gemfiles/sqlite/Gemfile +7 -0
- data/gemfiles/sqlite/Gemfile.lock +203 -0
- data/lib/active_record/union_relation/version.rb +1 -1
- data/lib/active_record/union_relation.rb +55 -24
- metadata +41 -31
- data/.mergify.yml +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0920889c3d3a7bd7ef4cd4e24fde9325418a7d2b108495265af571a3ff3cec88'
|
4
|
+
data.tar.gz: f056308e383a312cb440eab986a28d95788ae88ce14ffa1b5cac9799c4fd44b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4709e79f723b4cf9279f708eaf0a6860ba4b39d3411678ebf1ea7c34923c685af1ae8359004afcdf08178d90f629f355cb5aa98c7b0d1bdabcb5710ba8b28576
|
7
|
+
data.tar.gz: 106be365eb3f8d6e528d1617e9a95ede261a15c1603e2d147fd4452538190ce47a11d8f556135251591567fc864975b4f54c8bf9a8ca0d449d51d45dcd04552a
|
data/.github/dependabot.yml
CHANGED
@@ -4,3 +4,19 @@ updates:
|
|
4
4
|
directory: "/"
|
5
5
|
schedule:
|
6
6
|
interval: "daily"
|
7
|
+
- package-ecosystem: "bundler"
|
8
|
+
directory: "/gemfiles/mysql"
|
9
|
+
schedule:
|
10
|
+
interval: "daily"
|
11
|
+
- package-ecosystem: "bundler"
|
12
|
+
directory: "/gemfiles/postgresql"
|
13
|
+
schedule:
|
14
|
+
interval: "daily"
|
15
|
+
- package-ecosystem: "bundler"
|
16
|
+
directory: "/gemfiles/sqlite"
|
17
|
+
schedule:
|
18
|
+
interval: "daily"
|
19
|
+
- package-ecosystem: "github-actions"
|
20
|
+
directory: "/"
|
21
|
+
schedule:
|
22
|
+
interval: "daily"
|
@@ -0,0 +1,22 @@
|
|
1
|
+
name: Dependabot auto-merge
|
2
|
+
on: pull_request
|
3
|
+
|
4
|
+
permissions:
|
5
|
+
contents: write
|
6
|
+
pull-requests: write
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
dependabot:
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
if: ${{ github.actor == 'dependabot[bot]' }}
|
12
|
+
steps:
|
13
|
+
- name: Dependabot metadata
|
14
|
+
id: metadata
|
15
|
+
uses: dependabot/fetch-metadata@v1.6.0
|
16
|
+
with:
|
17
|
+
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
18
|
+
- name: Enable auto-merge for Dependabot PRs
|
19
|
+
run: gh pr merge --auto --merge "$PR_URL"
|
20
|
+
env:
|
21
|
+
PR_URL: ${{github.event.pull_request.html_url}}
|
22
|
+
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
data/.github/workflows/main.yml
CHANGED
@@ -1,11 +1,60 @@
|
|
1
1
|
name: Main
|
2
|
-
|
2
|
+
|
3
|
+
on:
|
4
|
+
- push
|
5
|
+
- pull_request
|
6
|
+
|
3
7
|
jobs:
|
4
|
-
|
5
|
-
name:
|
8
|
+
lint:
|
9
|
+
name: Lint
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
steps:
|
12
|
+
- run: sudo apt-get -yqq install libpq-dev libsqlite3-dev
|
13
|
+
- uses: actions/checkout@master
|
14
|
+
- uses: ruby/setup-ruby@v1
|
15
|
+
with:
|
16
|
+
ruby-version: '3.3'
|
17
|
+
bundler-cache: true
|
18
|
+
- name: Lint
|
19
|
+
run: bundle exec rake stree:check
|
20
|
+
mysql:
|
21
|
+
name: MySQL
|
6
22
|
runs-on: ubuntu-latest
|
7
23
|
env:
|
8
|
-
|
24
|
+
BUNDLE_GEMFILE: gemfiles/mysql/Gemfile
|
25
|
+
DATABASE_URL: mysql2://root:password@127.0.0.1:3306/test
|
26
|
+
RAILS_ENV: test
|
27
|
+
services:
|
28
|
+
mysql:
|
29
|
+
image: mysql:5.7
|
30
|
+
env:
|
31
|
+
MYSQL_DATABASE: test
|
32
|
+
MYSQL_USERNAME: root
|
33
|
+
MYSQL_PASSWORD: password
|
34
|
+
MYSQL_ROOT_PASSWORD: password
|
35
|
+
MYSQL_HOST: 127.0.0.1
|
36
|
+
MYSQL_PORT: 3306
|
37
|
+
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
38
|
+
ports:
|
39
|
+
- 3306:3306
|
40
|
+
options: >-
|
41
|
+
--health-cmd="mysqladmin ping"
|
42
|
+
--health-interval=10s
|
43
|
+
--health-timeout=5s
|
44
|
+
--health-retries=3
|
45
|
+
steps:
|
46
|
+
- uses: actions/checkout@master
|
47
|
+
- uses: ruby/setup-ruby@v1
|
48
|
+
with:
|
49
|
+
ruby-version: '3.3'
|
50
|
+
bundler-cache: true
|
51
|
+
- name: Test
|
52
|
+
run: bundle exec rake test
|
53
|
+
postgresql:
|
54
|
+
name: PostgreSQL
|
55
|
+
runs-on: ubuntu-latest
|
56
|
+
env:
|
57
|
+
BUNDLE_GEMFILE: gemfiles/postgresql/Gemfile
|
9
58
|
DATABASE_URL: postgres://postgres:@localhost:5432/postgres
|
10
59
|
RAILS_ENV: test
|
11
60
|
services:
|
@@ -23,17 +72,23 @@ jobs:
|
|
23
72
|
- uses: actions/checkout@master
|
24
73
|
- uses: ruby/setup-ruby@v1
|
25
74
|
with:
|
26
|
-
ruby-version:
|
27
|
-
|
75
|
+
ruby-version: '3.3'
|
76
|
+
bundler-cache: true
|
77
|
+
- name: Test
|
78
|
+
run: bundle exec rake test
|
79
|
+
sqlite:
|
80
|
+
name: SQLite
|
81
|
+
runs-on: ubuntu-latest
|
82
|
+
env:
|
83
|
+
BUNDLE_GEMFILE: gemfiles/sqlite/Gemfile
|
84
|
+
DATABASE_URL: "sqlite3::memory:"
|
85
|
+
RAILS_ENV: test
|
86
|
+
steps:
|
87
|
+
- run: sudo apt-get -yqq install libsqlite3-dev
|
88
|
+
- uses: actions/checkout@master
|
89
|
+
- uses: ruby/setup-ruby@v1
|
28
90
|
with:
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
- name: Install deps
|
34
|
-
run: |
|
35
|
-
bundle config path vendor/bundle
|
36
|
-
bundle install --jobs 4 --retry 3
|
37
|
-
- name: Lint and test
|
38
|
-
run: |
|
39
|
-
bundle exec rake test
|
91
|
+
ruby-version: '3.3'
|
92
|
+
bundler-cache: true
|
93
|
+
- name: Test
|
94
|
+
run: bundle exec rake test
|
data/CHANGELOG.md
CHANGED
@@ -6,11 +6,26 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [0.2.0] - 2024-02-09
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
- Support for sqlite.
|
14
|
+
- Support for scoped column names.
|
15
|
+
|
16
|
+
## [0.1.1] - 2021-11-17
|
17
|
+
|
18
|
+
### Changed
|
19
|
+
|
20
|
+
- Require MFA for releasing.
|
21
|
+
|
9
22
|
## [0.1.0] - 2020-10-08
|
10
23
|
|
11
24
|
### Added
|
12
25
|
|
13
26
|
- 🎉 Initial release. 🎉
|
14
27
|
|
15
|
-
[unreleased]: https://github.com/
|
16
|
-
[0.
|
28
|
+
[unreleased]: https://github.com/kddnewton/active_record-union_relation/compare/v0.2.0...HEAD
|
29
|
+
[0.2.0]: https://github.com/kddnewton/active_record-union_relation/compare/v0.1.1...v0.2.0
|
30
|
+
[0.1.1]: https://github.com/kddnewton/active_record-union_relation/compare/v0.1.0...v0.1.1
|
31
|
+
[0.1.0]: https://github.com/kddnewton/active_record-union_relation/compare/a71bb8...v0.1.0
|
data/CODE_OF_CONDUCT.md
CHANGED
@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
|
|
55
55
|
## Enforcement
|
56
56
|
|
57
57
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
-
reported by contacting the project team at
|
58
|
+
reported by contacting the project team at kddnewton@gmail.com. All
|
59
59
|
complaints will be reviewed and investigated and will result in a response that
|
60
60
|
is deemed necessary and appropriate to the circumstances. The project team is
|
61
61
|
obligated to maintain confidentiality with regard to the reporter of an incident.
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,146 +1,207 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
active_record-union_relation (0.
|
4
|
+
active_record-union_relation (0.2.0)
|
5
5
|
activerecord (>= 6)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
actioncable (
|
11
|
-
actionpack (=
|
10
|
+
actioncable (7.1.3)
|
11
|
+
actionpack (= 7.1.3)
|
12
|
+
activesupport (= 7.1.3)
|
12
13
|
nio4r (~> 2.0)
|
13
14
|
websocket-driver (>= 0.6.1)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
zeitwerk (~> 2.6)
|
16
|
+
actionmailbox (7.1.3)
|
17
|
+
actionpack (= 7.1.3)
|
18
|
+
activejob (= 7.1.3)
|
19
|
+
activerecord (= 7.1.3)
|
20
|
+
activestorage (= 7.1.3)
|
21
|
+
activesupport (= 7.1.3)
|
20
22
|
mail (>= 2.7.1)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
net-imap
|
24
|
+
net-pop
|
25
|
+
net-smtp
|
26
|
+
actionmailer (7.1.3)
|
27
|
+
actionpack (= 7.1.3)
|
28
|
+
actionview (= 7.1.3)
|
29
|
+
activejob (= 7.1.3)
|
30
|
+
activesupport (= 7.1.3)
|
25
31
|
mail (~> 2.5, >= 2.5.4)
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
32
|
+
net-imap
|
33
|
+
net-pop
|
34
|
+
net-smtp
|
35
|
+
rails-dom-testing (~> 2.2)
|
36
|
+
actionpack (7.1.3)
|
37
|
+
actionview (= 7.1.3)
|
38
|
+
activesupport (= 7.1.3)
|
39
|
+
nokogiri (>= 1.8.5)
|
40
|
+
racc
|
41
|
+
rack (>= 2.2.4)
|
42
|
+
rack-session (>= 1.0.1)
|
31
43
|
rack-test (>= 0.6.3)
|
32
|
-
rails-dom-testing (~> 2.
|
33
|
-
rails-html-sanitizer (~> 1.
|
34
|
-
actiontext (
|
35
|
-
actionpack (=
|
36
|
-
activerecord (=
|
37
|
-
activestorage (=
|
38
|
-
activesupport (=
|
44
|
+
rails-dom-testing (~> 2.2)
|
45
|
+
rails-html-sanitizer (~> 1.6)
|
46
|
+
actiontext (7.1.3)
|
47
|
+
actionpack (= 7.1.3)
|
48
|
+
activerecord (= 7.1.3)
|
49
|
+
activestorage (= 7.1.3)
|
50
|
+
activesupport (= 7.1.3)
|
51
|
+
globalid (>= 0.6.0)
|
39
52
|
nokogiri (>= 1.8.5)
|
40
|
-
actionview (
|
41
|
-
activesupport (=
|
53
|
+
actionview (7.1.3)
|
54
|
+
activesupport (= 7.1.3)
|
42
55
|
builder (~> 3.1)
|
43
|
-
erubi (~> 1.
|
44
|
-
rails-dom-testing (~> 2.
|
45
|
-
rails-html-sanitizer (~> 1.
|
46
|
-
activejob (
|
47
|
-
activesupport (=
|
56
|
+
erubi (~> 1.11)
|
57
|
+
rails-dom-testing (~> 2.2)
|
58
|
+
rails-html-sanitizer (~> 1.6)
|
59
|
+
activejob (7.1.3)
|
60
|
+
activesupport (= 7.1.3)
|
48
61
|
globalid (>= 0.3.6)
|
49
|
-
activemodel (
|
50
|
-
activesupport (=
|
51
|
-
activerecord (
|
52
|
-
activemodel (=
|
53
|
-
activesupport (=
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
62
|
+
activemodel (7.1.3)
|
63
|
+
activesupport (= 7.1.3)
|
64
|
+
activerecord (7.1.3)
|
65
|
+
activemodel (= 7.1.3)
|
66
|
+
activesupport (= 7.1.3)
|
67
|
+
timeout (>= 0.4.0)
|
68
|
+
activestorage (7.1.3)
|
69
|
+
actionpack (= 7.1.3)
|
70
|
+
activejob (= 7.1.3)
|
71
|
+
activerecord (= 7.1.3)
|
72
|
+
activesupport (= 7.1.3)
|
73
|
+
marcel (~> 1.0)
|
74
|
+
activesupport (7.1.3)
|
75
|
+
base64
|
76
|
+
bigdecimal
|
60
77
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
78
|
+
connection_pool (>= 2.2.5)
|
79
|
+
drb
|
80
|
+
i18n (>= 1.6, < 2)
|
81
|
+
minitest (>= 5.1)
|
82
|
+
mutex_m
|
83
|
+
tzinfo (~> 2.0)
|
84
|
+
base64 (0.2.0)
|
85
|
+
bigdecimal (3.1.6)
|
65
86
|
builder (3.2.4)
|
66
|
-
concurrent-ruby (1.
|
87
|
+
concurrent-ruby (1.2.3)
|
88
|
+
connection_pool (2.4.1)
|
67
89
|
crass (1.0.6)
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
90
|
+
date (3.3.4)
|
91
|
+
drb (2.2.0)
|
92
|
+
ruby2_keywords
|
93
|
+
erubi (1.12.0)
|
94
|
+
globalid (1.2.1)
|
95
|
+
activesupport (>= 6.1)
|
96
|
+
i18n (1.14.1)
|
72
97
|
concurrent-ruby (~> 1.0)
|
73
|
-
|
98
|
+
io-console (0.7.2)
|
99
|
+
irb (1.11.2)
|
100
|
+
rdoc
|
101
|
+
reline (>= 0.4.2)
|
102
|
+
loofah (2.22.0)
|
74
103
|
crass (~> 1.0.2)
|
75
|
-
nokogiri (>= 1.
|
76
|
-
mail (2.
|
104
|
+
nokogiri (>= 1.12.0)
|
105
|
+
mail (2.8.1)
|
77
106
|
mini_mime (>= 0.1.1)
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
mini_mime (1.
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
107
|
+
net-imap
|
108
|
+
net-pop
|
109
|
+
net-smtp
|
110
|
+
marcel (1.0.2)
|
111
|
+
mini_mime (1.1.5)
|
112
|
+
minitest (5.22.2)
|
113
|
+
mutex_m (0.2.0)
|
114
|
+
mysql2 (0.5.6)
|
115
|
+
net-imap (0.4.10)
|
116
|
+
date
|
117
|
+
net-protocol
|
118
|
+
net-pop (0.1.2)
|
119
|
+
net-protocol
|
120
|
+
net-protocol (0.2.2)
|
121
|
+
timeout
|
122
|
+
net-smtp (0.4.0.1)
|
123
|
+
net-protocol
|
124
|
+
nio4r (2.7.0)
|
125
|
+
nokogiri (1.16.2-arm64-darwin)
|
126
|
+
racc (~> 1.4)
|
127
|
+
nokogiri (1.16.2-x86_64-linux)
|
128
|
+
racc (~> 1.4)
|
129
|
+
pg (1.5.4)
|
130
|
+
prettier_print (1.2.1)
|
131
|
+
psych (5.1.2)
|
132
|
+
stringio
|
133
|
+
racc (1.7.3)
|
134
|
+
rack (3.0.9)
|
135
|
+
rack-session (2.0.0)
|
136
|
+
rack (>= 3.0.0)
|
137
|
+
rack-test (2.1.0)
|
138
|
+
rack (>= 1.3)
|
139
|
+
rackup (2.1.0)
|
140
|
+
rack (>= 3)
|
141
|
+
webrick (~> 1.8)
|
142
|
+
rails (7.1.3)
|
143
|
+
actioncable (= 7.1.3)
|
144
|
+
actionmailbox (= 7.1.3)
|
145
|
+
actionmailer (= 7.1.3)
|
146
|
+
actionpack (= 7.1.3)
|
147
|
+
actiontext (= 7.1.3)
|
148
|
+
actionview (= 7.1.3)
|
149
|
+
activejob (= 7.1.3)
|
150
|
+
activemodel (= 7.1.3)
|
151
|
+
activerecord (= 7.1.3)
|
152
|
+
activestorage (= 7.1.3)
|
153
|
+
activesupport (= 7.1.3)
|
154
|
+
bundler (>= 1.15.0)
|
155
|
+
railties (= 7.1.3)
|
156
|
+
rails-dom-testing (2.2.0)
|
157
|
+
activesupport (>= 5.0.0)
|
158
|
+
minitest
|
109
159
|
nokogiri (>= 1.6)
|
110
|
-
rails-html-sanitizer (1.
|
111
|
-
loofah (~> 2.
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
160
|
+
rails-html-sanitizer (1.6.0)
|
161
|
+
loofah (~> 2.21)
|
162
|
+
nokogiri (~> 1.14)
|
163
|
+
railties (7.1.3)
|
164
|
+
actionpack (= 7.1.3)
|
165
|
+
activesupport (= 7.1.3)
|
166
|
+
irb
|
167
|
+
rackup (>= 1.0.0)
|
168
|
+
rake (>= 12.2)
|
169
|
+
thor (~> 1.0, >= 1.2.2)
|
170
|
+
zeitwerk (~> 2.6)
|
171
|
+
rake (13.1.0)
|
172
|
+
rdoc (6.6.2)
|
173
|
+
psych (>= 4.0.0)
|
174
|
+
reline (0.4.2)
|
175
|
+
io-console (~> 0.5)
|
176
|
+
ruby2_keywords (0.0.5)
|
177
|
+
sqlite3 (1.7.2-arm64-darwin)
|
178
|
+
sqlite3 (1.7.2-x86_64-linux)
|
179
|
+
stringio (3.1.0)
|
180
|
+
syntax_tree (6.2.0)
|
181
|
+
prettier_print (>= 1.2.0)
|
182
|
+
thor (1.3.0)
|
183
|
+
timeout (0.4.1)
|
184
|
+
tzinfo (2.0.6)
|
120
185
|
concurrent-ruby (~> 1.0)
|
121
|
-
|
122
|
-
|
123
|
-
actionpack (>= 4.0)
|
124
|
-
activesupport (>= 4.0)
|
125
|
-
sprockets (>= 3.0.0)
|
126
|
-
thor (1.0.1)
|
127
|
-
thread_safe (0.3.6)
|
128
|
-
tzinfo (1.2.7)
|
129
|
-
thread_safe (~> 0.1)
|
130
|
-
websocket-driver (0.7.3)
|
186
|
+
webrick (1.8.1)
|
187
|
+
websocket-driver (0.7.6)
|
131
188
|
websocket-extensions (>= 0.1.0)
|
132
189
|
websocket-extensions (0.1.5)
|
133
|
-
zeitwerk (2.
|
190
|
+
zeitwerk (2.6.13)
|
134
191
|
|
135
192
|
PLATFORMS
|
136
|
-
|
193
|
+
arm64-darwin-22
|
194
|
+
x86_64-linux
|
137
195
|
|
138
196
|
DEPENDENCIES
|
139
197
|
active_record-union_relation!
|
140
|
-
minitest
|
141
|
-
|
142
|
-
|
143
|
-
|
198
|
+
minitest
|
199
|
+
mysql2
|
200
|
+
pg
|
201
|
+
rails
|
202
|
+
rake
|
203
|
+
sqlite3
|
204
|
+
syntax_tree
|
144
205
|
|
145
206
|
BUNDLED WITH
|
146
|
-
2.1
|
207
|
+
2.4.1
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# ActiveRecord::UnionRelation
|
2
2
|
|
3
|
-
[](https://github.com/kddnewton/active_record-union_relation/actions)
|
4
|
+
[](https://rubygems.org/gems/active_record-union_relation)
|
4
5
|
|
5
6
|
There are times when you want to use SQL's [UNION](https://www.w3schools.com/sql/sql_union.asp) operator to pull rows from multiple relations, but you still want to maintain the query-builder interface of ActiveRecord. This gem allows you to do that with minimal syntax.
|
6
7
|
|
@@ -9,7 +10,7 @@ There are times when you want to use SQL's [UNION](https://www.w3schools.com/sql
|
|
9
10
|
Add this line to your application's Gemfile:
|
10
11
|
|
11
12
|
```ruby
|
12
|
-
gem
|
13
|
+
gem "active_record-union_relation"
|
13
14
|
```
|
14
15
|
|
15
16
|
And then execute:
|
@@ -24,7 +25,7 @@ Or install it yourself as:
|
|
24
25
|
|
25
26
|
Let's assume you're writing something like a search function, and you want to be able to return a polymorphic relation containing all of the search results. You could maintain a separate index table with links out to the entities or use a more advanced search engine. Or you could perform a `UNION` that searches each table.
|
26
27
|
|
27
|
-
`UNION` subrelations must all have the same number of columns, so first we define the name of the columns that the `UNION` will select, then we define the sources that will become those columns from each subrelation. It makes
|
28
|
+
`UNION` subrelations must all have the same number of columns, so first we define the name of the columns that the `UNION` will select, then we define the sources that will become those columns from each subrelation. It makes more sense looking at an example.
|
28
29
|
|
29
30
|
Let's assume we have the following structure with default table names:
|
30
31
|
|
@@ -46,7 +47,7 @@ Now, let's pull all of the records matching a specific term. For `Post`, we'll p
|
|
46
47
|
```ruby
|
47
48
|
# Let's get a local variable that we'll use to reference within each of our
|
48
49
|
# subqueries. Presumably this would come from some kind of user input.
|
49
|
-
term =
|
50
|
+
term = "foo"
|
50
51
|
|
51
52
|
# First, we call ActiveRecord::union. The arguments are the names of the columns
|
52
53
|
# that will be aliased from each source relation. It also accepts a block that
|
@@ -58,7 +59,7 @@ relation =
|
|
58
59
|
# just for this one table. That can include any kind of
|
59
60
|
# joins/conditions/orders etc. that it needs to. In this case we'll need
|
60
61
|
# published: true and a matching query.
|
61
|
-
posts = Post.where(published: true).where(
|
62
|
+
posts = Post.where(published: true).where("title LIKE ?", "%#{term}%")
|
62
63
|
|
63
64
|
# Next, we'll add that posts relation as a subquery into the union. The
|
64
65
|
# number of arguments here must directly align with the number of arguments
|
@@ -73,12 +74,12 @@ relation =
|
|
73
74
|
# explicitly pulling post_id, we'll actually be able to call .post on the
|
74
75
|
# comment records that get pulled since we alias them back when we
|
75
76
|
# instantiate the objects.
|
76
|
-
comments = Comment.where(
|
77
|
+
comments = Comment.where("body LIKE ?", "%#{term}%")
|
77
78
|
union.add comments, :id, :post_id, :body
|
78
79
|
|
79
80
|
# Finally, we'll pull the tag records that we want and add them into the
|
80
81
|
# overall union as well.
|
81
|
-
tags = Tag.where(
|
82
|
+
tags = Tag.where("name LIKE ?", "%#{term}%")
|
82
83
|
union.add tags, :id, nil, :name
|
83
84
|
end
|
84
85
|
|
@@ -94,6 +95,20 @@ relation.order(matched: :asc)
|
|
94
95
|
# #<Comment:0x00 id: 3, post_id: 2, body: "This is a comment with foo in it">]
|
95
96
|
```
|
96
97
|
|
98
|
+
The query generated in the example above will look something like:
|
99
|
+
|
100
|
+
```sql
|
101
|
+
SELECT discriminator, id, post_id, matched
|
102
|
+
FROM (
|
103
|
+
(SELECT 'Post' AS "discriminator", id AS "id", NULL AS "post_id", title AS "matched" FROM "posts" WHERE "posts"."published" = $1 AND (title LIKE '%foo%'))
|
104
|
+
UNION
|
105
|
+
(SELECT 'Comment' AS "discriminator", id AS "id", post_id AS "post_id", body AS "matched" FROM "comments" WHERE (body LIKE '%foo%'))
|
106
|
+
UNION
|
107
|
+
(SELECT 'Tag' AS "discriminator", id AS "id", NULL AS "post_id", name AS "matched" FROM "tags" WHERE (name LIKE '%foo%'))
|
108
|
+
) AS "union"
|
109
|
+
ORDER BY "matched" ASC
|
110
|
+
```
|
111
|
+
|
97
112
|
## Development
|
98
113
|
|
99
114
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -102,7 +117,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
102
117
|
|
103
118
|
## Contributing
|
104
119
|
|
105
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
120
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/kddnewton/active_record-union_relation.
|
106
121
|
|
107
122
|
## License
|
108
123
|
|
data/Rakefile
CHANGED
@@ -1,12 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rake/testtask"
|
5
|
+
require "syntax_tree/rake_tasks"
|
5
6
|
|
6
7
|
Rake::TestTask.new(:test) do |t|
|
7
|
-
t.libs <<
|
8
|
-
t.libs <<
|
9
|
-
t.test_files = FileList[
|
8
|
+
t.libs << "test"
|
9
|
+
t.libs << "lib"
|
10
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
10
11
|
end
|
11
12
|
|
12
13
|
task default: :test
|
14
|
+
|
15
|
+
configure = ->(task) do
|
16
|
+
task.source_files =
|
17
|
+
FileList[%w[Gemfile Rakefile *.gemspec lib/**/*.rb test/**/*.rb]]
|
18
|
+
end
|
19
|
+
|
20
|
+
SyntaxTree::Rake::CheckTask.new(&configure)
|
21
|
+
SyntaxTree::Rake::WriteTask.new(&configure)
|