active_record_union 1.3.0 → 1.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 3b6908e8b32e304532e3b8405712ade67fab7e52
4
- data.tar.gz: 937298c6d470715b18510f2e317a7f3d735b2cf6
2
+ SHA256:
3
+ metadata.gz: b321a0fac09cf1cc331b5526f907b8dd78844796ed473093396dc08297997415
4
+ data.tar.gz: 020d7aca83f28ecfbf9455c48049f70c7fa0389ec72904c743fd724fd314ad05
5
5
  SHA512:
6
- metadata.gz: 8466c15bb3c268bbea28f49b3a85915e91f72bd43997462a4bd09a1da14ec9c85d5ca9621a6b7316ac04fe6949ccf4284bce854ed5b33c71bc492ca9bbd0cc9f
7
- data.tar.gz: a99a9d9c0c19e332d9b0c357310d886c72c5b7f629be97a0d8e2dcdc8d90dcb1605960f3a44a8dacdfe0749dc7dfe6f2571ebe27d63a6bcb1970e7798447a88f
6
+ metadata.gz: 35cb47fc2d57a16a74dbad2995cd90b87eecdea1a5aca340d8543cb504b73cd2a9cbbdb0e0c6cc4b71b416fcc04f3aa884f588067c316a0cc03dd60e9b5b376d
7
+ data.tar.gz: d0dff7b05b27f31b82d00ffe2f8cb5537b5c91a345ec31b02015cb31d020ace156277f8a9f6a8bac3c326f3890f5202213c909ec94435aac46a8be7a169b0ba9
@@ -0,0 +1,70 @@
1
+ name: RSpec Test Matrix
2
+ on:
3
+ push:
4
+ pull_request:
5
+
6
+ jobs:
7
+ test:
8
+ runs-on: ubuntu-latest
9
+
10
+ services:
11
+ postgresql:
12
+ image: postgres
13
+ ports:
14
+ - 5432:5432
15
+ options: >-
16
+ --health-cmd pg_isready
17
+ --health-interval 10s
18
+ --health-timeout 5s
19
+ --health-retries 5
20
+ env:
21
+ POSTGRES_DB: active_record_union
22
+ POSTGRES_USER: active_record_union
23
+ POSTGRES_PASSWORD: active_record_union
24
+
25
+ mysql2:
26
+ image: mysql:8.0
27
+ env:
28
+ MYSQL_DATABASE: active_record_union
29
+ MYSQL_ROOT_PASSWORD: active_record_union
30
+ options: >-
31
+ --health-cmd "mysqladmin ping"
32
+ --health-interval 10s
33
+ --health-timeout 5s
34
+ ports:
35
+ - "3306:3306"
36
+
37
+ strategy:
38
+ fail-fast: false
39
+ matrix:
40
+ # just define specific versions for each rails version
41
+ include:
42
+ - ruby: 2.6
43
+ rails: "6.0"
44
+ - ruby: "3.0"
45
+ rails: 6.1
46
+ - ruby: 3.1
47
+ rails: "7.0"
48
+ - ruby: 3.2
49
+ rails: 7.1
50
+ - ruby: 3.2
51
+ rails: 7.2
52
+ - ruby: 3.3
53
+ rails: "8.0"
54
+
55
+ env:
56
+ BUNDLE_GEMFILE: "rails_${{ matrix.rails }}.gemfile"
57
+ DB_HOST: 127.0.0.1
58
+ MYSQL_ROOT_HOST: "%"
59
+ MYSQL_DB: active_record_union
60
+ MYSQL_USER: root
61
+ MYSQL_PASSWORD: active_record_union
62
+ steps:
63
+ - uses: actions/checkout@v4
64
+
65
+ - uses: ruby/setup-ruby@v1
66
+ with:
67
+ ruby-version: ${{ matrix.ruby }}
68
+ bundler-cache: true # install gems and cache
69
+
70
+ - run: bundle exec rspec --force-color --format d
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ # this is just a convenience for out of the box development
2
+ source 'https://rubygems.org'
3
+
4
+ eval_gemfile File.expand_path('./rails_8.0.gemfile', __dir__)
data/README.md CHANGED
@@ -17,7 +17,9 @@ user_1.posts.union(user_2.posts).union(Post.published)
17
17
  user_1.posts.union_all(user_2.posts)
18
18
  ```
19
19
 
20
- ActiveRecordUnion is tested against Rails 4.2 and Rails 5.0. It may or may not work on Rails 4.0/4.1.
20
+ ActiveRecordUnion is tested against Rails 6.0, 6.1, 7.0, 7.1, 7.2 and 8.0.
21
+
22
+ If you are using Postgres, you might alternatively check out [ActiveRecordExtended](https://github.com/georgekaraszi/ActiveRecordExtended) which includes support for unions as well as other goodies.
21
23
 
22
24
  ## Installation
23
25
 
@@ -186,6 +188,9 @@ This is a gem not a Rails pull request because the standard of code quality for
186
188
 
187
189
  ## Changelog
188
190
 
191
+ **1.4.0** - October 1, 2025
192
+ - Ready for Rails 8.0! Support for Rails < 6 dropped. Updates provided by [@timdiggins](https://github.com/frederikspang) and [@frederikspang](https://github.com/frederikspang).
193
+
189
194
  **1.3.0** - January 14, 2018
190
195
  - Ready for Rails 5.2! Updates provided by [@glebm](https://github.com/glebm).
191
196
 
@@ -214,9 +219,9 @@ This public domain dedication follows the the CC0 1.0 at https://creativecommons
214
219
  2. Create your feature branch (`git checkout -b my-new-feature`)
215
220
  3. Run the tests:
216
221
  1. Install MySQL and PostgreSQL.
217
- 2. You need to be able to connect to a local MySQL and Postgres database as the default user, so the specs can create a `test_active_record_union` database. From a vanilla install of MariaDB from Homebrew, this just works. For Postgres installed by Homebrew, you may need to run `$ echo "create database my_computer_user_name;" | psql postgres` since the initial database created by Homebrew is named "postgres" but PG defaults to connecting to a database named after your username.
222
+ 2. You need to be able to connect to a local MySQL and Postgres database as the default user, so the specs can create a `test_active_record_union` database. To set up the users this test expects, execute `bin/create-db-users` (or set the environment variables referenced in `spec/support/databases.rb`).
218
223
  3. Run `rake` to test with all supported Rails versions. All needed dependencies will be installed via Bundler (`gem install bundler` if you happen not to have Bundler yet).
219
- 4. Run `rake test_rails_4_2` or `rake test_rails_5_2` etc. to test a specific Rails version.
224
+ 4. Run `rake test_rails_8_0` or `rake test_rails_7_2` etc. to test a specific Rails version.
220
225
  4. There is also a `bin/console` command to load up a REPL for playing around
221
226
  5. Commit your changes (`git commit -am 'Add some feature'`)
222
227
  6. Push to the branch (`git push origin my-new-feature`)
data/Rakefile CHANGED
@@ -51,11 +51,11 @@ end
51
51
 
52
52
 
53
53
  TestTasks.gemfiles.each do |gemfile|
54
- rails_version_underscored = gemfile[/rails_(.+)\.gemfile/, 1]
54
+ rails_version = gemfile[/rails_(.+)\.gemfile/, 1]
55
55
 
56
- desc "Test Rails #{rails_version_underscored.gsub("_", ".")}"
57
- task :"test_rails_#{rails_version_underscored}" do
56
+ desc "Test Rails #{rails_version}"
57
+ task :"test_rails_#{rails_version.gsub(".", "_")}" do
58
58
  env = { 'BUNDLE_GEMFILE' => gemfile }
59
59
  TestTasks.run_one(env)
60
60
  end
61
- end
61
+ end
@@ -18,13 +18,10 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) + spec.files.grep(%r{^bin/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_dependency "activerecord", ">= 4.0"
21
+ spec.add_dependency "activerecord", ">= 6.0"
22
22
 
23
- spec.add_development_dependency "bundler", "~> 1.6"
23
+ spec.add_development_dependency "bundler"
24
24
  spec.add_development_dependency "rake"
25
25
  spec.add_development_dependency "rspec", "~> 3.0"
26
26
  spec.add_development_dependency "pry"
27
- spec.add_development_dependency "sqlite3"
28
- spec.add_development_dependency "pg"
29
- spec.add_development_dependency "mysql2"
30
27
  end
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env bash
2
+
3
+ GREEN='\033[0;32m'
4
+ RESET_COLOR='\033[0m'
5
+
6
+ if [ -n "$1" ]; then cat <<'HELP'; exit; fi
7
+ Usage: bin/create-db-users
8
+ Create the active_record_union database users for all the supported databases.
9
+ If the `DB` environment variable is set, do the above only for that database.
10
+ HELP
11
+
12
+ USER='active_record_union'
13
+ PASS='active_record_union'
14
+
15
+ set -e
16
+ log() { if [ -t 1 ]; then echo -e >&2 "${GREEN}create-db-users: $@${RESET_COLOR}"; else echo >&2 "$@"; fi }
17
+
18
+ create_mysql_user() {
19
+ if mysql -s -u"$USER" -p"$PASS" -e '' 2>/dev/null; then return; fi
20
+ log "Creating MySQL '$USER' user. MySQL root password required."
21
+ mysql --verbose -uroot -p <<SQL
22
+ CREATE USER '$USER'@'localhost' IDENTIFIED BY '$PASS';
23
+ GRANT ALL PRIVILEGES ON \`test_active_record_union\`.* TO '$USER'@'localhost';
24
+ SQL
25
+ }
26
+
27
+ create_postgresql_user() {
28
+ if PGPASSWORD="$PASS" psql -h 127.0.0.1 postgres -U $USER -c ''; then return; fi
29
+ log "Creating Postgres '$USER' user."
30
+ local cmd='psql postgres'
31
+ if ! $cmd -c '' 2>/dev/null; then
32
+ log "sudo required:"
33
+ cmd="sudo -u ${PG_DAEMON_USER:-postgres} psql postgres"
34
+ fi
35
+ # need to also create database first time
36
+ $cmd --echo-all <<SQL
37
+ CREATE ROLE $USER LOGIN PASSWORD '$PASS';
38
+ ALTER ROLE $USER CREATEDB;
39
+ CREATE DATABASE active_record_union;
40
+ SQL
41
+ }
42
+
43
+ [ -z "$DB" -o "$DB" = 'mysql2' ] && create_mysql_user
44
+ [ -z "$DB" -o "$DB" = 'postgresql' ] && create_postgresql_user
@@ -21,7 +21,7 @@ module ActiveRecord
21
21
  other = if args.empty? && relation_or_where_arg.is_a?(Relation)
22
22
  relation_or_where_arg
23
23
  else
24
- @klass.where(relation_or_where_arg, *args)
24
+ self.klass.where(relation_or_where_arg, *args)
25
25
  end
26
26
 
27
27
  verify_relations_for_set_operation!(operation, self, other)
@@ -37,45 +37,12 @@ module ActiveRecord
37
37
  end
38
38
 
39
39
  set = SET_OPERATION_TO_AREL_CLASS[operation].new(left, right)
40
- from = Arel::Nodes::TableAlias.new(set, @klass.arel_table.name)
40
+ from = Arel::Nodes::TableAlias.new(set, self.klass.arel_table.name)
41
41
  build_union_relation(from, other)
42
42
  end
43
43
 
44
- if ActiveRecord.gem_version >= Gem::Version.new('5.2.0.beta2')
45
- # Since Rails 5.2, binds are maintained only in the Arel AST.
46
- def build_union_relation(arel_table_alias, _other)
47
- @klass.unscoped.from(arel_table_alias)
48
- end
49
- elsif ActiveRecord::VERSION::MAJOR >= 5
50
- # In Rails >= 5.0, < 5.2, binds are maintained only in ActiveRecord
51
- # relations and clauses.
52
- def build_union_relation(arel_table_alias, other)
53
- relation = @klass.unscoped.spawn
54
- relation.from_clause =
55
- UnionFromClause.new(arel_table_alias, nil,
56
- self.bound_attributes + other.bound_attributes)
57
- relation
58
- end
59
-
60
- class UnionFromClause < ActiveRecord::Relation::FromClause
61
- def initialize(value, name, bound_attributes)
62
- super(value, name)
63
- @bound_attributes = bound_attributes
64
- end
65
-
66
- def binds
67
- @bound_attributes
68
- end
69
- end
70
- else
71
- # In Rails 4.x, binds are maintained in both ActiveRecord relations and
72
- # clauses and also in their Arel ASTs.
73
- def build_union_relation(arel_table_alias, other)
74
- relation = @klass.unscoped.from(arel_table_alias)
75
- relation.bind_values = self.arel.bind_values + self.bind_values +
76
- other.arel.bind_values + other.bind_values
77
- relation
78
- end
44
+ def build_union_relation(arel_table_alias, _other)
45
+ self.klass.unscoped.from(arel_table_alias)
79
46
  end
80
47
 
81
48
  def verify_relations_for_set_operation!(operation, *relations)
@@ -1,3 +1,3 @@
1
1
  module ActiveRecordUnion
2
- VERSION = "1.3.0"
2
+ VERSION = "1.4.0"
3
3
  end
data/rails_6.0.gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in active_record_union.gemspec
4
+ gemspec
5
+
6
+ gem 'rails', '~> 6.0.0'
7
+
8
+ # https://github.com/rails/rails/blob/v6.0.6.1/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
9
+ gem "pg", ">= 0.18", "< 2.0"
10
+
11
+ # https://github.com/rails/rails/blob/v6.0.2/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#L13
12
+ gem "sqlite3", "~> 1.4"
13
+
14
+ # https://github.com/rails/rails/blob/v6.0.6.1/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
15
+ gem "mysql2", ">= 0.4.4"
16
+
data/rails_6.1.gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in active_record_union.gemspec
4
+ gemspec
5
+
6
+ gem 'rails', '~> 6.1.0'
7
+
8
+ # https://github.com/rails/rails/blob/v6.1.7.10/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
9
+ gem "pg", "~> 1.1"
10
+
11
+ # https://github.com/rails/rails/blob/v6.1.2/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#L13
12
+ gem "sqlite3", "~> 1.4"
13
+
14
+ # https://github.com/rails/rails/blob/v6.1.7.10/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
15
+ gem "mysql2", "~> 0.5"
16
+
data/rails_7.0.gemfile ADDED
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in active_record_union.gemspec
6
+ gemspec
7
+
8
+ gem 'rails', '~> 7.0.0'
9
+
10
+ # https://github.com/rails/rails/blob/v7.0.2/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#L13
11
+ gem 'sqlite3', '~> 1.4'
12
+
13
+ # https://github.com/rails/rails/blob/v7.0.2/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L4
14
+ gem 'pg', '~> 1.1'
15
+
16
+ # https://github.com/rails/rails/blob/v7.0.2/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb#L6
17
+ gem 'mysql2', '~> 0.5'
data/rails_7.1.gemfile ADDED
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in active_record_union.gemspec
6
+ gemspec
7
+
8
+ gem 'rails', '~> 7.1.0'
9
+
10
+ # https://github.com/rails/rails/blob/v7.1.2/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#L13
11
+ gem 'sqlite3', '~> 1.4'
12
+
13
+ # https://github.com/rails/rails/blob/v7.1.2/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L4
14
+ gem 'pg', '~> 1.1'
15
+
16
+ # https://github.com/rails/rails/blob/v7.1.2/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb#L6
17
+ gem 'mysql2', '~> 0.5'
data/rails_7.2.gemfile ADDED
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in active_record_union.gemspec
6
+ gemspec
7
+
8
+ gem 'rails', '~> 7.2.0'
9
+
10
+ # https://github.com/rails/rails/blob/v7.2.0/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#L13
11
+ gem 'sqlite3', '>= 1.4'
12
+
13
+ # https://github.com/rails/rails/blob/v7.2.0/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L4
14
+ gem 'pg', '~> 1.1'
15
+
16
+ # https://github.com/rails/rails/blob/v7.2.0/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb#L6
17
+ gem 'mysql2', '~> 0.5'
data/rails_8.0.gemfile ADDED
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in active_record_union.gemspec
6
+ gemspec
7
+
8
+ gem 'rails', '~> 8.0.0'
9
+
10
+ # https://github.com/rails/rails/blob/main/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#L13
11
+ gem 'sqlite3', '>= 2.1'
12
+
13
+ # https://github.com/rails/rails/blob/main/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L4
14
+ gem 'pg', '~> 1.1'
15
+
16
+ # https://github.com/rails/rails/blob/main/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb#L6
17
+ gem 'mysql2', '~> 0.5'
data/spec/spec_helper.rb CHANGED
@@ -9,6 +9,7 @@ Databases.connect_to_sqlite
9
9
 
10
10
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
11
11
  RSpec.configure do |config|
12
+ config.backtrace_inclusion_patterns << %r{gems/([0-9.])+/gems/(?!rspec|capybara)} if ENV['BACKTRACE']
12
13
  # Run specs in random order to surface order dependencies. If you find an
13
14
  # order dependency and want to debug it, you can fix the order by providing
14
15
  # the seed, which is printed after each run.
@@ -11,24 +11,47 @@ module Databases
11
11
 
12
12
  def connect_to_postgres
13
13
  ActiveRecord::Base.establish_connection(
14
- adapter: "postgresql"
14
+ adapter: "postgresql",
15
+ host: ENV.fetch('DB_HOST', 'localhost'),
16
+ username: ENV.fetch("POSTGRES_USER", 'active_record_union'),
17
+ password: ENV.fetch("POSTGRES_PASSWORD", 'active_record_union')
15
18
  )
16
- ActiveRecord::Base.connection.recreate_database("test_active_record_union")
19
+ try_to_drop_database
20
+ ActiveRecord::Base.connection.create_database("test_active_record_union")
17
21
  ActiveRecord::Base.establish_connection(
18
22
  adapter: "postgresql",
19
- database: "test_active_record_union"
23
+ host: ENV.fetch('DB_HOST', 'localhost'),
24
+ username: ENV.fetch("POSTGRES_USER", 'active_record_union'),
25
+ password: ENV.fetch("POSTGRES_PASSWORD", 'active_record_union'),
26
+ database: ENV.fetch("POSTGRES_DB", "test_active_record_union")
20
27
  )
21
28
  load("support/models.rb")
22
29
  end
23
30
 
31
+ def try_to_drop_database
32
+ ActiveRecord::Base.connection.drop_database("test_active_record_union")
33
+ rescue ActiveRecord::NoDatabaseError
34
+ $stderr.puts "Can't drop database 'test_active_record_union' as it doesn't exist"
35
+ rescue ActiveRecord::ActiveRecordError => e
36
+ $stderr.puts "Can't drop database 'test_active_record_union' (but continuing anyway): #{e}"
37
+ rescue => e
38
+ $stderr.puts "Other error (#{e.class.name}) dropping database 'test_active_record_union' (but continuing anyway): #{e}"
39
+ end
40
+
24
41
  def connect_to_mysql
25
42
  ActiveRecord::Base.establish_connection(
26
- adapter: "mysql2"
43
+ adapter: "mysql2",
44
+ host: ENV.fetch('DB_HOST', 'localhost'),
45
+ username: ENV.fetch("MYSQL_USER", "active_record_union"),
46
+ password: ENV.fetch("MYSQL_PASSWORD", "active_record_union")
27
47
  )
28
48
  ActiveRecord::Base.connection.recreate_database("test_active_record_union")
29
49
  ActiveRecord::Base.establish_connection(
30
50
  adapter: "mysql2",
31
- database: "test_active_record_union"
51
+ host: ENV.fetch('DB_HOST', 'localhost'),
52
+ username: ENV.fetch("MYSQL_USER", "active_record_union"),
53
+ password: ENV.fetch("MYSQL_PASSWORD", "active_record_union"),
54
+ database: ENV.fetch("MYSQL_DB", "test_active_record_union")
32
55
  )
33
56
  load("support/models.rb")
34
57
  end
data/spec/union_spec.rb CHANGED
@@ -2,7 +2,7 @@ require "spec_helper"
2
2
 
3
3
  describe ActiveRecord::Relation do
4
4
  TIME = Time.utc(2014, 7, 19, 0, 0, 0)
5
- SQL_TIME = ActiveRecord::VERSION::MAJOR >= 5 ? "2014-07-19 00:00:00" : "2014-07-19 00:00:00.000000"
5
+ SQL_TIME = "2014-07-19 00:00:00"
6
6
 
7
7
  describe ".union" do
8
8
  it "returns an ActiveRecord::Relation" do
@@ -34,22 +34,30 @@ describe ActiveRecord::Relation do
34
34
  expect(union.to_sql.squish).to eq(
35
35
  "SELECT \"posts\".* FROM ( SELECT \"posts\".* FROM \"posts\" WHERE \"posts\".\"user_id\" = 1 UNION SELECT \"posts\".* FROM \"posts\" WHERE (created_at > '#{SQL_TIME}') ) \"posts\""
36
36
  )
37
- expect(union.arel.to_sql.squish).to eq(
38
- "SELECT \"posts\".* FROM ( SELECT \"posts\".* FROM \"posts\" WHERE \"posts\".\"user_id\" = ? UNION SELECT \"posts\".* FROM \"posts\" WHERE (created_at > '#{SQL_TIME}') ) \"posts\""
39
- )
40
- expect{union.to_a}.to_not raise_error
37
+ if ActiveRecord.version >= Gem::Version.new("7.2.0")
38
+ expect(union.arel.to_sql.squish).to eq(
39
+ "SELECT \"posts\".* FROM ( SELECT \"posts\".* FROM \"posts\" WHERE \"posts\".\"user_id\" = ? UNION SELECT \"posts\".* FROM \"posts\" WHERE (created_at > ?) ) \"posts\""
40
+ )
41
+ expect(bind_values_from_arel(union.arel, Post.arel_table)).to eq([1, TIME])
42
+ else
43
+ expect(union.arel.to_sql.squish).to eq(
44
+ "SELECT \"posts\".* FROM ( SELECT \"posts\".* FROM \"posts\" WHERE \"posts\".\"user_id\" = ? UNION SELECT \"posts\".* FROM \"posts\" WHERE (created_at > '#{SQL_TIME}') ) \"posts\""
45
+ )
46
+ expect(bind_values_from_arel(union.arel, Post.arel_table)).to eq([1])
47
+ end
48
+ expect { union.to_a }.to_not raise_error
41
49
  end
42
50
 
43
51
  def bind_values_from_relation(relation)
44
- if ActiveRecord.gem_version >= Gem::Version.new('5.2.0.beta2')
45
- relation.arel_table.class.engine.connection.visitor.accept(
46
- relation.arel.ast, Arel::Collectors::Bind.new
47
- ).value.map(&:value)
48
- elsif ActiveRecord::VERSION::MAJOR >= 5
49
- relation.bound_attributes.map { |a| a.value_for_database }
50
- else
51
- (relation.arel.bind_values + relation.bind_values).map { |_column, value| value }
52
- end
52
+ bind_values_from_arel(relation.arel, relation.arel_table)
53
+ end
54
+
55
+ def bind_values_from_arel(arel, arel_table)
56
+ collector = Arel::Collectors::Bind.new
57
+ collector.define_singleton_method(:preparable=) { |_preparable| } if ActiveRecord.version.between?(Gem::Version.new("6.1.0"), Gem::Version.new("7.2.99"))
58
+ arel_table.class.engine.connection.visitor.accept(
59
+ arel.ast, collector
60
+ ).value.map { |v| v.try(:value) || v }
53
61
  end
54
62
 
55
63
  it "binds values properly" do
@@ -72,16 +80,16 @@ describe ActiveRecord::Relation do
72
80
  bind_values = bind_values_from_relation union
73
81
  expect(bind_values).to eq([true, 11])
74
82
 
75
-
76
83
  expect(union.to_sql.squish).to eq(
77
- "SELECT \"users\".* FROM ( SELECT \"users\".* FROM \"users\" INNER JOIN \"posts\" ON \"posts\".\"user_id\" = \"users\".\"id\" AND \"posts\".\"draft\" = 't' UNION SELECT \"users\".* FROM \"users\" WHERE \"users\".\"id\" = 11 ) \"users\""
84
+ "SELECT \"users\".* FROM ( SELECT \"users\".* FROM \"users\" INNER JOIN \"posts\" ON \"posts\".\"draft\" = 1 AND \"posts\".\"user_id\" = \"users\".\"id\" UNION SELECT \"users\".* FROM \"users\" WHERE \"users\".\"id\" = 11 ) \"users\""
78
85
  )
79
86
  expect{union.to_a}.to_not raise_error
80
87
  end
81
88
 
82
89
  it "doesn't repeat default scopes" do
83
90
  expect(Time).to receive(:now) { Time.utc(2014, 7, 24, 0, 0, 0) }
84
- sql_now = "2014-07-24 00:00:00#{".000000" if ActiveRecord::VERSION::MAJOR < 5}"
91
+
92
+ sql_now = "2014-07-24 00:00:00"
85
93
 
86
94
  class PublishedPost < ActiveRecord::Base
87
95
  self.table_name = "posts"
@@ -105,9 +113,15 @@ describe ActiveRecord::Relation do
105
113
 
106
114
  context "in SQLite" do
107
115
  it "lets ORDER BY in query subselects throw a syntax error" do
108
- expect(union.to_sql.squish).to eq(
109
- "SELECT \"posts\".* FROM ( SELECT \"posts\".* FROM \"posts\" WHERE \"posts\".\"user_id\" = 1 ORDER BY \"posts\".\"created_at\" ASC UNION SELECT \"posts\".* FROM \"posts\" WHERE (created_at > '#{SQL_TIME}') ORDER BY \"posts\".\"created_at\" ASC ) \"posts\" ORDER BY \"posts\".\"created_at\" ASC"
110
- )
116
+ if ActiveRecord.version >= Gem::Version.new("7.2.0")
117
+ expect(union.to_sql.squish).to eq(
118
+ "SELECT \"posts\".* FROM ( (SELECT \"posts\".* FROM \"posts\" WHERE \"posts\".\"user_id\" = 1 ORDER BY \"posts\".\"created_at\" ASC) UNION (SELECT \"posts\".* FROM \"posts\" WHERE (created_at > '2014-07-19 00:00:00') ORDER BY \"posts\".\"created_at\" ASC) ) \"posts\" ORDER BY \"created_at\" ASC"
119
+ )
120
+ else
121
+ expect(union.to_sql.squish).to eq(
122
+ "SELECT \"posts\".* FROM ( SELECT \"posts\".* FROM \"posts\" WHERE \"posts\".\"user_id\" = 1 ORDER BY \"posts\".\"created_at\" ASC UNION SELECT \"posts\".* FROM \"posts\" WHERE (created_at > '2014-07-19 00:00:00') ORDER BY \"posts\".\"created_at\" ASC ) \"posts\" ORDER BY \"created_at\" ASC"
123
+ )
124
+ end
111
125
  expect{union.to_a}.to raise_error(ActiveRecord::StatementInvalid)
112
126
  end
113
127
  end
@@ -116,8 +130,9 @@ describe ActiveRecord::Relation do
116
130
  it "wraps query subselects in parentheses to allow ORDER BY clauses" do
117
131
  Databases.with_postgres do
118
132
  expect(union.to_sql.squish).to eq(
119
- "SELECT \"posts\".* FROM ( (SELECT \"posts\".* FROM \"posts\" WHERE \"posts\".\"user_id\" = 1 ORDER BY \"posts\".\"created_at\" ASC) UNION (SELECT \"posts\".* FROM \"posts\" WHERE (created_at > '#{SQL_TIME}') ORDER BY \"posts\".\"created_at\" ASC) ) \"posts\" ORDER BY \"posts\".\"created_at\" ASC"
133
+ "SELECT \"posts\".* FROM ( (SELECT \"posts\".* FROM \"posts\" WHERE \"posts\".\"user_id\" = 1 ORDER BY \"posts\".\"created_at\" ASC) UNION (SELECT \"posts\".* FROM \"posts\" WHERE (created_at > '2014-07-19 00:00:00') ORDER BY \"posts\".\"created_at\" ASC) ) \"posts\" ORDER BY \"created_at\" ASC"
120
134
  )
135
+
121
136
  expect{union.to_a}.to_not raise_error
122
137
  end
123
138
  end
@@ -127,8 +142,9 @@ describe ActiveRecord::Relation do
127
142
  it "wraps query subselects in parentheses to allow ORDER BY clauses" do
128
143
  Databases.with_mysql do
129
144
  expect(union.to_sql.squish).to eq(
130
- "SELECT `posts`.* FROM ( (SELECT `posts`.* FROM `posts` WHERE `posts`.`user_id` = 1 ORDER BY `posts`.`created_at` ASC) UNION (SELECT `posts`.* FROM `posts` WHERE (created_at > '#{SQL_TIME}') ORDER BY `posts`.`created_at` ASC) ) `posts` ORDER BY `posts`.`created_at` ASC"
145
+ "SELECT `posts`.* FROM ( (SELECT `posts`.* FROM `posts` WHERE `posts`.`user_id` = 1 ORDER BY `posts`.`created_at` ASC) UNION (SELECT `posts`.* FROM `posts` WHERE (created_at > '2014-07-19 00:00:00') ORDER BY `posts`.`created_at` ASC) ) `posts` ORDER BY `created_at` ASC"
131
146
  )
147
+
132
148
  expect{union.to_a}.to_not raise_error
133
149
  end
134
150
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_union
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Hempel
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-14 00:00:00.000000000 Z
11
+ date: 2025-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4.0'
19
+ version: '6.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '4.0'
26
+ version: '6.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '1.6'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '1.6'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -80,48 +80,6 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: sqlite3
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: pg
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: mysql2
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
83
  description: UNIONs in ActiveRecord! Adds proper union and union_all methods to ActiveRecord::Relation.
126
84
  email:
127
85
  - plasticchicken@gmail.com
@@ -129,20 +87,24 @@ executables: []
129
87
  extensions: []
130
88
  extra_rdoc_files: []
131
89
  files:
90
+ - ".github/workflows/testing.yml"
132
91
  - ".gitignore"
133
- - ".travis.yml"
92
+ - Gemfile
134
93
  - LICENSE.txt
135
94
  - README.md
136
95
  - Rakefile
137
96
  - active_record_union.gemspec
138
97
  - bin/console
98
+ - bin/create-db-users
139
99
  - lib/active_record_union.rb
140
100
  - lib/active_record_union/active_record/relation/union.rb
141
101
  - lib/active_record_union/version.rb
142
- - rails_4_2.gemfile
143
- - rails_5_0.gemfile
144
- - rails_5_1.gemfile
145
- - rails_5_2.gemfile
102
+ - rails_6.0.gemfile
103
+ - rails_6.1.gemfile
104
+ - rails_7.0.gemfile
105
+ - rails_7.1.gemfile
106
+ - rails_7.2.gemfile
107
+ - rails_8.0.gemfile
146
108
  - spec/spec_helper.rb
147
109
  - spec/support/databases.rb
148
110
  - spec/support/models.rb
@@ -151,7 +113,7 @@ homepage: https://github.com/brianhempel/active_record_union
151
113
  licenses:
152
114
  - Public Domain
153
115
  metadata: {}
154
- post_install_message:
116
+ post_install_message:
155
117
  rdoc_options: []
156
118
  require_paths:
157
119
  - lib
@@ -166,9 +128,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
166
128
  - !ruby/object:Gem::Version
167
129
  version: '0'
168
130
  requirements: []
169
- rubyforge_project:
170
- rubygems_version: 2.6.8
171
- signing_key:
131
+ rubygems_version: 3.4.10
132
+ signing_key:
172
133
  specification_version: 4
173
134
  summary: UNIONs in ActiveRecord! Adds proper union and union_all methods to ActiveRecord::Relation.
174
135
  test_files:
@@ -177,3 +138,4 @@ test_files:
177
138
  - spec/support/models.rb
178
139
  - spec/union_spec.rb
179
140
  - bin/console
141
+ - bin/create-db-users
data/.travis.yml DELETED
@@ -1,11 +0,0 @@
1
- language: ruby
2
- addons:
3
- postgresql: "9.4"
4
- rvm:
5
- - 2.3.6
6
- gemfile:
7
- - rails_4_2.gemfile
8
- - rails_5_0.gemfile
9
- - rails_5_1.gemfile
10
- - rails_5_2.gemfile
11
- script: bundle exec rspec
data/rails_4_2.gemfile DELETED
@@ -1,11 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in active_record_union.gemspec
4
- gemspec
5
-
6
- gem 'rails', '~> 4.2.7'
7
-
8
- # On Rails < 5.2, only pg < v1 is supported. See:
9
- # https://github.com/rails/rails/pull/31671
10
- # https://bitbucket.org/ged/ruby-pg/issues/270/pg-100-x64-mingw32-rails-server-not-start
11
- gem 'pg', '~> 0.21'
data/rails_5_0.gemfile DELETED
@@ -1,11 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in active_record_union.gemspec
4
- gemspec
5
-
6
- gem 'rails', '~> 5.0.0'
7
-
8
- # On Rails < 5.2, only pg < v1 is supported. See:
9
- # https://github.com/rails/rails/pull/31671
10
- # https://bitbucket.org/ged/ruby-pg/issues/270/pg-100-x64-mingw32-rails-server-not-start
11
- gem 'pg', '~> 0.21'
data/rails_5_1.gemfile DELETED
@@ -1,11 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in active_record_union.gemspec
4
- gemspec
5
-
6
- gem 'rails', '~> 5.1.0'
7
-
8
- # On Rails < 5.2, only pg < v1 is supported. See:
9
- # https://github.com/rails/rails/pull/31671
10
- # https://bitbucket.org/ged/ruby-pg/issues/270/pg-100-x64-mingw32-rails-server-not-start
11
- gem 'pg', '~> 0.21'
data/rails_5_2.gemfile DELETED
@@ -1,7 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in active_record_union.gemspec
4
- gemspec
5
-
6
- # pg v1.0+ compatibility, https://github.com/rails/rails/pull/31671:
7
- gem 'rails', '~> 5.2.0.beta2', git: 'https://github.com/rails/rails', ref: 'f1af27fd9d9101684b26d0dcf2028859d67bec1f'