activerecord-virtual_attributes 2.0.0 → 6.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +8 -6
- data/.github/workflows/ci.yaml +69 -0
- data/.rubocop.yml +3 -2
- data/.rubocop_cc.yml +3 -3
- data/.whitesource +3 -0
- data/CHANGELOG.md +39 -16
- data/Gemfile +3 -3
- data/README.md +12 -10
- data/activerecord-virtual_attributes.gemspec +5 -4
- data/lib/active_record/virtual_attributes/version.rb +1 -1
- data/lib/active_record/virtual_attributes/virtual_arel.rb +118 -13
- data/lib/active_record/virtual_attributes/virtual_delegates.rb +19 -14
- data/lib/active_record/virtual_attributes/virtual_fields.rb +83 -298
- data/lib/active_record/virtual_attributes/virtual_total.rb +44 -28
- data/lib/active_record/virtual_attributes.rb +1 -23
- metadata +31 -23
- data/.travis.yml +0 -30
- data/Appraisals +0 -23
- data/gemfiles/gemfile_50.gemfile +0 -10
- data/gemfiles/gemfile_51.gemfile +0 -10
- data/gemfiles/gemfile_52.gemfile +0 -10
- data/gemfiles/gemfile_60.gemfile +0 -10
- data/lib/active_record/virtual_attributes/arel_groups.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a35d6c7665469341b76ae68e1a84180ccef887c47f56b7000efc2f0024d0a93
|
4
|
+
data.tar.gz: ba57d73a5034e461d3c6bd77a50eb5475d1fe0dab8c3332f91142c893fa736a2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55f8e509034dc3a13dae283733da176c308d25538c38595cebfd98008d07be372c0843752e547be6afb5af361fd1610900f05fc52cdcdfbd8bff834b66233060
|
7
|
+
data.tar.gz: c4511ba748f911a985f308bdfa61f9d6c64c57ec1245003dea509205f3aa4e0085f20f7e9adb5674d3657d750c34e6c4d64d41ee5faebb18846c9e8ef3ea4c32
|
data/.codeclimate.yml
CHANGED
@@ -1,11 +1,14 @@
|
|
1
|
-
---
|
2
1
|
version: '2'
|
3
2
|
prepare:
|
4
3
|
fetch:
|
5
|
-
- url: https://raw.githubusercontent.com/ManageIQ/
|
4
|
+
- url: https://raw.githubusercontent.com/ManageIQ/manageiq-style/master/.rubocop_base.yml
|
6
5
|
path: ".rubocop_base.yml"
|
7
|
-
- url: https://raw.githubusercontent.com/ManageIQ/
|
6
|
+
- url: https://raw.githubusercontent.com/ManageIQ/manageiq-style/master/.rubocop_cc_base.yml
|
8
7
|
path: ".rubocop_cc_base.yml"
|
8
|
+
- url: https://raw.githubusercontent.com/ManageIQ/manageiq-style/master/styles/base.yml
|
9
|
+
path: styles/base.yml
|
10
|
+
- url: https://raw.githubusercontent.com/ManageIQ/manageiq-style/master/styles/cc_base.yml
|
11
|
+
path: styles/cc_base.yml
|
9
12
|
checks:
|
10
13
|
argument-count:
|
11
14
|
enabled: false
|
@@ -27,6 +30,5 @@ checks:
|
|
27
30
|
plugins:
|
28
31
|
rubocop:
|
29
32
|
enabled: true
|
30
|
-
|
31
|
-
|
32
|
-
file: ".rubocop_cc.yml"
|
33
|
+
config: ".rubocop_cc.yml"
|
34
|
+
channel: rubocop-0-82
|
@@ -0,0 +1,69 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
pull_request:
|
6
|
+
schedule:
|
7
|
+
- cron: '0 0 * * 0'
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
ci:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
strategy:
|
13
|
+
matrix:
|
14
|
+
ruby-version:
|
15
|
+
- '2.7'
|
16
|
+
services:
|
17
|
+
postgres:
|
18
|
+
image: postgres:13
|
19
|
+
env:
|
20
|
+
POSTGRES_PASSWORD: password
|
21
|
+
POSTGRES_DB: virtual_attributes
|
22
|
+
options: --health-cmd pg_isready --health-interval 2s --health-timeout 5s --health-retries 5
|
23
|
+
ports:
|
24
|
+
- 5432:5432
|
25
|
+
mysql:
|
26
|
+
image: mysql:8.0
|
27
|
+
env:
|
28
|
+
MYSQL_ROOT_PASSWORD: password
|
29
|
+
MYSQL_DATABASE: virtual_attributes
|
30
|
+
options: --health-cmd="mysqladmin ping -h 127.0.0.1 -P 3306 --silent" --health-interval 10s --health-timeout 5s --health-retries 3
|
31
|
+
ports:
|
32
|
+
- 3306:3306
|
33
|
+
env:
|
34
|
+
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
35
|
+
# for the pg cli (psql, pg_isready) and rails
|
36
|
+
PGHOST: localhost
|
37
|
+
PGPORT: 5432
|
38
|
+
PGUSER: postgres
|
39
|
+
PGPASSWORD: password
|
40
|
+
# for the mysql cli (mysql, mysqladmin)
|
41
|
+
MYSQL_HOST: 127.0.0.1
|
42
|
+
MYSQL_PWD: password
|
43
|
+
steps:
|
44
|
+
- uses: actions/checkout@v2
|
45
|
+
- name: Set up Ruby
|
46
|
+
uses: ruby/setup-ruby@v1
|
47
|
+
with:
|
48
|
+
ruby-version: ${{ matrix.ruby-version }}
|
49
|
+
bundler-cache: true
|
50
|
+
timeout-minutes: 30
|
51
|
+
- name: Run SQLite tests
|
52
|
+
env:
|
53
|
+
DB: sqlite3
|
54
|
+
run: bundle exec rake
|
55
|
+
- name: Run PostgreSQL tests
|
56
|
+
env:
|
57
|
+
DB: pg
|
58
|
+
COLLATE_SYMBOLS: false
|
59
|
+
run: bundle exec rake
|
60
|
+
- name: Run MySQL tests
|
61
|
+
env:
|
62
|
+
DB: mysql2
|
63
|
+
run: bundle exec rake
|
64
|
+
- name: Report code coverage
|
65
|
+
if: ${{ github.ref == 'refs/heads/master' && matrix.ruby-version == '2.7' }}
|
66
|
+
continue-on-error: true
|
67
|
+
uses: paambaati/codeclimate-action@v3.0.0
|
68
|
+
env:
|
69
|
+
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
data/.rubocop.yml
CHANGED
data/.rubocop_cc.yml
CHANGED
@@ -1,4 +1,4 @@
|
|
1
1
|
inherit_from:
|
2
|
-
- .rubocop_base.yml
|
3
|
-
- .rubocop_cc_base.yml
|
4
|
-
- .rubocop_local.yml
|
2
|
+
- ".rubocop_base.yml"
|
3
|
+
- ".rubocop_cc_base.yml"
|
4
|
+
- ".rubocop_local.yml"
|
data/.whitesource
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,23 +1,43 @@
|
|
1
|
-
#
|
1
|
+
# Change Log
|
2
2
|
|
3
|
-
|
4
|
-
a nice looking [Changelog](http://keepachangelog.com).
|
3
|
+
The versioning of this gem follows ActiveRecord versioning, and does not follow SemVer. See the [README](./README.md) for more details.
|
5
4
|
|
6
|
-
##
|
5
|
+
## [Unreleased]
|
7
6
|
|
8
|
-
##
|
7
|
+
## [6.1.1] - 2022-08-09
|
8
|
+
|
9
|
+
* fix HomogeneousIn clauses [#111](https://github.com/ManageIQ/activerecord-virtual_attributes/pull/111)
|
10
|
+
|
11
|
+
## [6.1.0] - 2022-02-03
|
12
|
+
|
13
|
+
* **BREAKING** Dropped support for Rails 5.0, 5.1, 5.2, 6.0
|
14
|
+
* **BREAKING** This gem will now no longer follow Semantic Versioning,
|
15
|
+
but instead follow Rails' versioning numbers in order to simplify version
|
16
|
+
matches between them both.
|
17
|
+
* Added Rails 6.1 support
|
18
|
+
* Ruby 3.0 compatibility: kwargs, regular expression fixes
|
19
|
+
* changed extension mechanism from `arel_attribute()` to `arel_table[]`
|
20
|
+
* Auto add grouping to virtual attribute arel
|
21
|
+
|
22
|
+
## [3.0.0] - 2020-09-28
|
23
|
+
|
24
|
+
* fix virtual_aggregate to return a consistent 0 when calculating a sum of no records
|
25
|
+
* fix virtual delegate to include the type column when fetching associated models for polymorphism
|
26
|
+
* add virtual_average, virtual_minimum, and virtual_maximum
|
27
|
+
|
28
|
+
## [2.0.0] - 2020-05-22
|
9
29
|
|
10
30
|
* This is a trivial release, but because it modifies a public interface, the jump makes it look significant.
|
11
|
-
* removed legacy virtual_column parameter support. (it is not ruby 2.7 compatible)
|
31
|
+
* **BREAKING** removed legacy virtual_column parameter support. (it is not ruby 2.7 compatible)
|
12
32
|
* fixed warnings in ruby 2.7
|
13
33
|
|
14
|
-
##
|
34
|
+
## [1.6.0] - 2019-12-02
|
15
35
|
|
16
36
|
* rails 5.2 support
|
17
37
|
* fix Arel#name error
|
18
38
|
* Display deprecation notices for invalid associations (rather than throw an error)
|
19
39
|
|
20
|
-
##
|
40
|
+
## [1.5.0] - 2019-12-02
|
21
41
|
|
22
42
|
* `select()` no longer modifies `select_values`. It understands virtual attributes at a lower level.
|
23
43
|
* `includes()` can now handle all proper values presented.
|
@@ -26,22 +46,22 @@ a nice looking [Changelog](http://keepachangelog.com).
|
|
26
46
|
* rails 6.0 support, (rails 5.2 only fails `habtm` preloading)
|
27
47
|
* ruby 2.6.x support (no longer testing ruby 2.4)
|
28
48
|
|
29
|
-
##
|
49
|
+
## [1.4.0] - 2019-07-13
|
30
50
|
|
31
51
|
* fix includes to include all associations
|
32
52
|
* fix bin/console to now actually run
|
33
53
|
* select no longer munges field attribute
|
34
54
|
* support virtual attributes in left_outer_joins
|
35
55
|
|
36
|
-
##
|
56
|
+
## [1.3.1] - 2019-06-06
|
37
57
|
|
38
58
|
* quote column aliases
|
39
59
|
|
40
|
-
##
|
60
|
+
## [1.3.0] - 2019-05-24
|
41
61
|
|
42
62
|
* Rails 5.2 support
|
43
63
|
|
44
|
-
##
|
64
|
+
## [1.2.0] - 2019-04-23
|
45
65
|
|
46
66
|
* Virtual_delegate :type now specified to avoid rare race conditions with attribute discovery
|
47
67
|
* Delays interpreting delegate until column is used
|
@@ -49,24 +69,27 @@ a nice looking [Changelog](http://keepachangelog.com).
|
|
49
69
|
* More flexible includes. e.g.: Arrays of symbols now work
|
50
70
|
* Raises errors for invalid `includes()` and `:uses`
|
51
71
|
|
52
|
-
##
|
72
|
+
## [1.1.0] - 2019-04-23
|
53
73
|
|
54
74
|
* Add legacy types for `VirtualAttribute::Types`
|
55
75
|
* Fix rails 5.1 bug with `includes()`
|
56
76
|
* Remove reference to `MiqPreloader`
|
57
77
|
|
58
|
-
##
|
78
|
+
## [1.0.0] - 2019-03-05
|
59
79
|
|
60
80
|
* Renamed to activerecord-virtual_attributes
|
61
81
|
* Moved from ManageIQ to own repo
|
62
82
|
* Added support for Rails 5.1
|
63
83
|
|
64
|
-
##
|
84
|
+
## 0.1.0 - 2019-01-17
|
65
85
|
|
66
86
|
* Initial Release
|
67
87
|
* Extracted from ManageIQ/manageiq
|
68
88
|
|
69
|
-
[Unreleased]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/
|
89
|
+
[Unreleased]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v6.1.1...HEAD
|
90
|
+
[6.1.1]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v6.1.0...v6.1.1
|
91
|
+
[6.1.0]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v3.0.0...v6.1.0
|
92
|
+
[3.0.0]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v2.0.0...v3.0.0
|
70
93
|
[2.0.0]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v1.6.0...v2.0.0
|
71
94
|
[1.6.0]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v1.5.0...v1.6.0
|
72
95
|
[1.5.0]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v1.4.0...v1.5.0
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,20 +1,22 @@
|
|
1
1
|
# VirtualAttributes
|
2
2
|
|
3
|
-
[![
|
3
|
+
[![CI](https://github.com/ManageIQ/activerecord-virtual_attributes/actions/workflows/ci.yaml/badge.svg)](https://github.com/ManageIQ/activerecord-virtual_attributes/actions/workflows/ci.yaml)
|
4
4
|
[![Maintainability](https://api.codeclimate.com/v1/badges/e1a0c26941c00f4edb55/maintainability)](https://codeclimate.com/github/ManageIQ/activerecord-virtual_attributes/maintainability)
|
5
5
|
[![Test Coverage](https://api.codeclimate.com/v1/badges/e1a0c26941c00f4edb55/test_coverage)](https://codeclimate.com/github/ManageIQ/activerecord-virtual_attributes/test_coverage)
|
6
|
-
[![Security](https://hakiri.io/github/ManageIQ/activerecord-virtual_attributes/master.svg)](https://hakiri.io/github/ManageIQ/activerecord-virtual_attributes/master)
|
7
6
|
|
8
|
-
|
7
|
+
VirtualAttributes allows you to define a ruby method that acts like an attribute or relation.
|
9
8
|
|
10
|
-
Sometimes you have a model with an attribute defined in ruby
|
11
|
-
Well, to filter by that attribute, you need to fetch all the rows from the database and filter it in ruby.
|
12
|
-
For large tables, this is slow and takes up a lot of memory
|
9
|
+
Sometimes you have a model with an attribute defined in ruby but you want to sort or filter by it. Filtering by that attribute necessitates fetching all the rows from the database and filtering in ruby. For large tables, this is slow and takes up a lot of memory.
|
13
10
|
|
14
|
-
This gem allows you to represent these
|
11
|
+
This gem allows you to represent these attributes in sql so `ORDER BY` `WHERE` clauses will work.
|
15
12
|
|
16
|
-
This
|
17
|
-
|
13
|
+
This also allows you to calculate counts and treat those as a field accessible with `select(:child_count)` to get rid of the N+1 problem of running a `count(*)` on a subcollection for each row.
|
14
|
+
|
15
|
+
## Versioning
|
16
|
+
|
17
|
+
As of v6.1.0, the versioning of this gem follows ActiveRecord versioning, and does not follow SemVer (e.g. virtual attributes v6.1.x supports all versions of Rails 6.1). Version v3.0.0 supports Rails 6.0 and lower.
|
18
|
+
|
19
|
+
Use the latest version of both this gem and Rails where the first 2 digits match.
|
18
20
|
|
19
21
|
## Installation
|
20
22
|
|
@@ -45,7 +47,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
45
47
|
|
46
48
|
To test with different versions of ruby, use `wwtd` gem or
|
47
49
|
|
48
|
-
DB=pg BUNDLE_GEMFILE=gemfiles/gemfile_${version-52}.gemfile
|
50
|
+
DB=pg BUNDLE_GEMFILE=gemfiles/gemfile_${version-52}.gemfile bundle exec rake
|
49
51
|
|
50
52
|
## Contributing
|
51
53
|
|
@@ -25,11 +25,12 @@ Gem::Specification.new do |spec|
|
|
25
25
|
|
26
26
|
spec.require_paths = ["lib"]
|
27
27
|
|
28
|
-
spec.add_runtime_dependency "activerecord", "
|
28
|
+
spec.add_runtime_dependency "activerecord", "~> 6.1.0"
|
29
29
|
|
30
|
-
spec.add_development_dependency "appraisal"
|
31
30
|
spec.add_development_dependency "byebug"
|
32
|
-
spec.add_development_dependency "
|
31
|
+
spec.add_development_dependency "db-query-matchers"
|
32
|
+
spec.add_development_dependency "manageiq-style"
|
33
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
33
34
|
spec.add_development_dependency "rspec", "~> 3.0"
|
34
|
-
spec.add_development_dependency "simplecov"
|
35
|
+
spec.add_development_dependency "simplecov", ">= 0.21.2"
|
35
36
|
end
|
@@ -9,11 +9,59 @@ module ActiveRecord
|
|
9
9
|
#
|
10
10
|
# Model.select(Model.arel_table.grouping(Model.arel_table[:field2]).as(:field))
|
11
11
|
# Model.attribute_supported_by_sql?(:field) # => true
|
12
|
+
|
13
|
+
# in essence, this is our Arel::Nodes::VirtualAttribute
|
12
14
|
class Arel::Nodes::Grouping
|
13
|
-
attr_accessor :name
|
15
|
+
attr_accessor :name, :relation
|
16
|
+
|
17
|
+
# methods from Arel::Nodes::Attribute
|
18
|
+
def type_caster
|
19
|
+
relation.type_for_attribute(name)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Create a node for lowering this attribute
|
23
|
+
def lower
|
24
|
+
relation.lower(self)
|
25
|
+
end
|
26
|
+
|
27
|
+
def type_cast_for_database(value)
|
28
|
+
relation.type_cast_for_database(name, value)
|
29
|
+
end
|
30
|
+
|
31
|
+
# rubocop:disable Rails/Delegate
|
32
|
+
def able_to_type_cast?
|
33
|
+
relation.able_to_type_cast?
|
34
|
+
end
|
35
|
+
# rubocop:enable Rails/Delegate
|
14
36
|
end
|
15
37
|
|
16
38
|
module VirtualArel
|
39
|
+
# This arel table proxy is our shim to get our functionality into rails
|
40
|
+
class ArelTableProxy < Arel::Table
|
41
|
+
attr_accessor :klass
|
42
|
+
|
43
|
+
# overrides Arel::Table#[]
|
44
|
+
# adds aliases and virtual attribute arel (aka sql)
|
45
|
+
#
|
46
|
+
# @returns Arel::Attributes::Attribute|Arel::Nodes::Grouping|Nil
|
47
|
+
# for regular database columns:
|
48
|
+
# returns an Arel::Attribute (just like Arel::Table#[])
|
49
|
+
# for virtual attributes:
|
50
|
+
# returns the arel for the value
|
51
|
+
# for non sql friendly virtual attributes:
|
52
|
+
# returns nil
|
53
|
+
def [](name, table = self)
|
54
|
+
if (col_alias = @klass.attribute_alias(name))
|
55
|
+
name = col_alias
|
56
|
+
end
|
57
|
+
if @klass.virtual_attribute?(name)
|
58
|
+
@klass.arel_for_virtual_attribute(name, table)
|
59
|
+
else
|
60
|
+
super
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
17
65
|
extend ActiveSupport::Concern
|
18
66
|
|
19
67
|
included do
|
@@ -22,20 +70,19 @@ module ActiveRecord
|
|
22
70
|
end
|
23
71
|
|
24
72
|
module ClassMethods
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
super
|
73
|
+
if ActiveRecord.version.to_s < "6.1"
|
74
|
+
# ActiveRecord::Core 6.0 (every version of active record seems to do this differently)
|
75
|
+
def arel_table
|
76
|
+
@arel_table ||= ArelTableProxy.new(table_name, :type_caster => type_caster).tap { |t| t.klass = self }
|
77
|
+
end
|
78
|
+
else
|
79
|
+
# ActiveRecord::Core 6.1
|
80
|
+
def arel_table
|
81
|
+
@arel_table ||= ArelTableProxy.new(table_name, :klass => self)
|
35
82
|
end
|
36
83
|
end
|
37
84
|
|
38
|
-
# supported by sql if
|
85
|
+
# supported by sql if any are true:
|
39
86
|
# - it is an attribute alias
|
40
87
|
# - it is an attribute that is non virtual
|
41
88
|
# - it is an attribute that is virtual and has arel defined
|
@@ -45,12 +92,70 @@ module ActiveRecord
|
|
45
92
|
(has_attribute?(name) && (!virtual_attribute?(name) || !!_virtual_arel[name.to_s]))
|
46
93
|
end
|
47
94
|
|
95
|
+
# private api
|
96
|
+
#
|
97
|
+
# @return [Nil|Arel::Nodes::Grouping]
|
98
|
+
# for virtual attributes:
|
99
|
+
# returns the arel for the column
|
100
|
+
# for non sql friendly virtual attributes:
|
101
|
+
# returns nil
|
102
|
+
def arel_for_virtual_attribute(column_name, table) # :nodoc:
|
103
|
+
arel_lambda = _virtual_arel[column_name.to_s]
|
104
|
+
return unless arel_lambda
|
105
|
+
|
106
|
+
arel = arel_lambda.call(table)
|
107
|
+
arel = Arel::Nodes::Grouping.new(arel) unless arel.kind_of?(Arel::Nodes::Grouping)
|
108
|
+
arel.name = column_name
|
109
|
+
arel.relation = table
|
110
|
+
arel
|
111
|
+
end
|
112
|
+
|
48
113
|
private
|
49
114
|
|
50
|
-
def define_virtual_arel(name, arel)
|
115
|
+
def define_virtual_arel(name, arel) # :nodoc:
|
51
116
|
self._virtual_arel = _virtual_arel.merge(name => arel)
|
52
117
|
end
|
53
118
|
end
|
54
119
|
end
|
55
120
|
end
|
56
121
|
end
|
122
|
+
|
123
|
+
module Arel # :nodoc: all
|
124
|
+
# rubocop:disable Naming/MethodName
|
125
|
+
# rubocop:disable Naming/MethodParameterName
|
126
|
+
# rubocop:disable Style/ConditionalAssignment
|
127
|
+
module Visitors
|
128
|
+
# rails 6.1...
|
129
|
+
class ToSql
|
130
|
+
private
|
131
|
+
|
132
|
+
def visit_Arel_Nodes_HomogeneousIn(o, collector)
|
133
|
+
collector.preparable = false
|
134
|
+
|
135
|
+
# change:
|
136
|
+
# See https://github.com/rails/rails/pull/45642
|
137
|
+
visit(o.left, collector)
|
138
|
+
# /change
|
139
|
+
|
140
|
+
if o.type == :in
|
141
|
+
collector << " IN ("
|
142
|
+
else
|
143
|
+
collector << " NOT IN ("
|
144
|
+
end
|
145
|
+
|
146
|
+
values = o.casted_values
|
147
|
+
|
148
|
+
if values.empty?
|
149
|
+
collector << @connection.quote(nil)
|
150
|
+
else
|
151
|
+
collector.add_binds(values, o.proc_for_binds, &bind_block)
|
152
|
+
end
|
153
|
+
|
154
|
+
collector << ")"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
# rubocop:enable Naming/MethodName
|
159
|
+
# rubocop:enable Naming/MethodParameterName
|
160
|
+
# rubocop:enable Style/ConditionalAssignment
|
161
|
+
end
|
@@ -151,14 +151,9 @@ module ActiveRecord
|
|
151
151
|
# There is currently no way to propagate sql over a virtual association
|
152
152
|
if reflect_on_association(to_ref.name) && (to_ref.macro == :has_one || to_ref.macro == :belongs_to)
|
153
153
|
lambda do |t|
|
154
|
-
|
155
|
-
to_ref.join_keys
|
156
|
-
else
|
157
|
-
to_ref.join_keys(to_ref.klass)
|
158
|
-
end
|
159
|
-
src_model_id = arel_attribute(join_keys.foreign_key, t)
|
154
|
+
src_model_id = arel_table[to_ref.join_foreign_key, t]
|
160
155
|
blk = ->(arel) { arel.limit = 1 } if to_ref.macro == :has_one
|
161
|
-
VirtualDelegates.select_from_alias(to_ref, col,
|
156
|
+
VirtualDelegates.select_from_alias(to_ref, col, to_ref.join_primary_key, src_model_id, &blk)
|
162
157
|
end
|
163
158
|
end
|
164
159
|
end
|
@@ -240,6 +235,7 @@ module ActiveRecord
|
|
240
235
|
# (SELECT "vms_sub"."name" FROM "vms" AS "vms_ss" WHERE "vms_ss"."id" = "vms"."src_template_id")
|
241
236
|
#
|
242
237
|
|
238
|
+
# Based upon ActiveRecord AssociationScope.scope
|
243
239
|
def self.select_from_alias(to_ref, col, to_model_col_name, src_model_id)
|
244
240
|
query = if to_ref.scope
|
245
241
|
to_ref.klass.instance_exec(nil, &to_ref.scope)
|
@@ -247,16 +243,25 @@ module ActiveRecord
|
|
247
243
|
to_ref.klass.all
|
248
244
|
end
|
249
245
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
246
|
+
src_model = to_ref.active_record
|
247
|
+
to_table = select_from_alias_table(to_ref.klass, src_model_id.relation)
|
248
|
+
to_model_id = to_ref.klass.arel_table[to_model_col_name, to_table]
|
249
|
+
to_column = to_ref.klass.arel_table[col, to_table]
|
250
|
+
arel = query.except(:select).select(to_column).arel
|
251
|
+
.from(to_table)
|
252
|
+
.where(to_model_id.eq(src_model_id))
|
253
|
+
|
254
|
+
# :type is in the reflection definition (meaning it is polymorphic)
|
255
|
+
if to_ref.type
|
256
|
+
# get the class name (e.g. "Host")
|
257
|
+
polymorphic_type = src_model.base_class.name
|
258
|
+
arel = arel.where(to_ref.klass.arel_table[to_ref.type].eq(polymorphic_type))
|
259
|
+
end
|
256
260
|
|
257
261
|
yield arel if block_given?
|
258
262
|
|
259
|
-
|
263
|
+
# convert arel to sql to populate with bind variables
|
264
|
+
::Arel::Nodes::Grouping.new(Arel.sql(arel.to_sql))
|
260
265
|
end
|
261
266
|
|
262
267
|
# determine table reference to use for a sub query
|