activerecord-virtual_attributes 1.5.0 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 90da25c212d7507da2ca2789b1151b2e7cb7cb3936411a7e92823518299141b9
4
- data.tar.gz: d2a3cc1662d29fa8625dab40610950a573c0014b9739dbb260184da47afdb2ac
3
+ metadata.gz: eb60079c2b76281f9ace2d7f4a25c9956d9c439c408b6d0df615cb8c4512a31f
4
+ data.tar.gz: 6eb95ac5ea930cd875c73e8fcfaca826e3f69370417489f9c074c2c90795e71e
5
5
  SHA512:
6
- metadata.gz: 78c1edd3d1a17f5f4fcd147315e37c788cdfc3add3137a4190d568cc93ab1823d9de0e46a6f57f266d248104823578d5f6a86e076228ae640c52c035922910f4
7
- data.tar.gz: 19ec2fafe3553b4ff809c1aae1aa6ccfd6f303216d1c35bc4a09f30e9dda2876a48fd531d9216e0a1a566de0434c90edd58936c12027b62bc9c70eb896235b50
6
+ metadata.gz: e0d8221e8ee5ce87f5082c7e3e7b821375e0da1c6109bd772c1ee01fb396de12169c3f6ac53cdddd267d7974785b81ca0047ccf4b0ed43278b79bdb84c2cd557
7
+ data.tar.gz: 0b980f5df648db206618fd304ac54fd69f84ed53e004226629ddcc389775686934291baaf106cf196b0fe5204107046bf437f6db12b41a632a62dba88c71b0a0
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/guides/master/.rubocop_base.yml
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/guides/master/.rubocop_cc_base.yml
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
- channel: "rubocop-0-67"
31
- config:
32
- file: ".rubocop_cc.yml"
33
+ config: ".rubocop_cc.yml"
34
+ channel: rubocop-0-82
@@ -0,0 +1,74 @@
1
+ name: CI
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ ci:
7
+ runs-on: ubuntu-latest
8
+ strategy:
9
+ matrix:
10
+ ruby-version:
11
+ - '2.7'
12
+ services:
13
+ postgres:
14
+ image: postgres:13
15
+ env:
16
+ POSTGRES_PASSWORD: password
17
+ POSTGRES_DB: virtual_attributes
18
+ ports:
19
+ - 5432:5432
20
+ options: >-
21
+ --health-cmd pg_isready
22
+ --health-interval 2s
23
+ --health-timeout 5s
24
+ --health-retries 5
25
+ mysql:
26
+ image: mysql:8.0
27
+ env:
28
+ MYSQL_ROOT_PASSWORD: password
29
+ MYSQL_DATABASE: virtual_attributes
30
+ ports:
31
+ - 3306:3306
32
+ options: >-
33
+ --health-cmd="mysqladmin ping -h 127.0.0.1 -P 3306 --silent"
34
+ --health-interval 10s
35
+ --health-timeout 5s
36
+ --health-retries 3
37
+ env:
38
+ # for the pg cli (psql, pg_isready) and possibly rails
39
+ PGHOST: localhost
40
+ PGPORT: 5432
41
+ PGUSER: postgres
42
+ PGPASSWORD: password
43
+ # for the mysql cli (mysql, mysqladmin)
44
+ MYSQL_HOST: 127.0.0.1
45
+ MYSQL_PWD: password
46
+ steps:
47
+ - uses: actions/checkout@v2
48
+ - name: Set up Ruby
49
+ uses: ruby/setup-ruby@v1
50
+ with:
51
+ ruby-version: ${{ matrix.ruby-version }}
52
+ bundler-cache: true
53
+ - name: Run SQLite tests
54
+ env:
55
+ DB: sqlite3
56
+ CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
57
+ run: bundle exec rake
58
+ - name: Run Postgres tests
59
+ env:
60
+ DB: pg
61
+ COLLATE_SYMBOLS: false
62
+ CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
63
+ run: bundle exec rake
64
+ - name: Run MySQL tests
65
+ env:
66
+ DB: mysql2
67
+ CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
68
+ run: bundle exec rake
69
+ - if: ${{ github.ref == 'refs/heads/master' && matrix.ruby-version == '2.7' }}
70
+ name: Report code coverage
71
+ continue-on-error: true
72
+ uses: paambaati/codeclimate-action@v3.0.0
73
+ env:
74
+ CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
data/.rubocop.yml CHANGED
@@ -1,3 +1,4 @@
1
1
  inherit_from:
2
- - https://raw.githubusercontent.com/ManageIQ/guides/master/.rubocop_base.yml
3
- - .rubocop_local.yml
2
+ - ".rubocop_local.yml"
3
+ inherit_gem:
4
+ manageiq-style: ".rubocop_base.yml"
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
@@ -0,0 +1,3 @@
1
+ {
2
+ "settingsInheritedFrom": "ManageIQ/whitesource-config@master"
3
+ }
data/CHANGELOG.md CHANGED
@@ -1,11 +1,43 @@
1
- # Virtual Attributes Changelog
1
+ # Change Log
2
2
 
3
- Doing our best at supporting [SemVer](http://semver.org/) with
4
- a nice looking [Changelog](http://keepachangelog.com).
3
+ Versioning of this gem follows ActiveRecord versioning, and does not follow SemVer.
5
4
 
6
- ## Version [Unreleased]
5
+ e.g.: virtual attributes 6.1.x supports all versions of rails 6.1.
7
6
 
8
- ## Version [1.5.0] <small>2019-12-02</small>
7
+ Use the latest version of both this gem and rails where the first 2 digits match.
8
+
9
+ ## [Unreleased]
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
29
+
30
+ * This is a trivial release, but because it modifies a public interface, the jump makes it look significant.
31
+ * **BREAKING** removed legacy virtual_column parameter support. (it is not ruby 2.7 compatible)
32
+ * fixed warnings in ruby 2.7
33
+
34
+ ## [1.6.0] - 2019-12-02
35
+
36
+ * rails 5.2 support
37
+ * fix Arel#name error
38
+ * Display deprecation notices for invalid associations (rather than throw an error)
39
+
40
+ ## [1.5.0] - 2019-12-02
9
41
 
10
42
  * `select()` no longer modifies `select_values`. It understands virtual attributes at a lower level.
11
43
  * `includes()` can now handle all proper values presented.
@@ -14,22 +46,22 @@ a nice looking [Changelog](http://keepachangelog.com).
14
46
  * rails 6.0 support, (rails 5.2 only fails `habtm` preloading)
15
47
  * ruby 2.6.x support (no longer testing ruby 2.4)
16
48
 
17
- ## Version [1.4.0] <small>2019-07-13</small>
49
+ ## [1.4.0] - 2019-07-13
18
50
 
19
51
  * fix includes to include all associations
20
52
  * fix bin/console to now actually run
21
53
  * select no longer munges field attribute
22
54
  * support virtual attributes in left_outer_joins
23
55
 
24
- ## Version [1.3.1] <small>2019-06-06</small>
56
+ ## [1.3.1] - 2019-06-06
25
57
 
26
58
  * quote column aliases
27
59
 
28
- ## Version [1.3.0] <small>2019-05-24</small>
60
+ ## [1.3.0] - 2019-05-24
29
61
 
30
62
  * Rails 5.2 support
31
63
 
32
- ## Version [1.2.0] <small>2019-04-23</small>
64
+ ## [1.2.0] - 2019-04-23
33
65
 
34
66
  * Virtual_delegate :type now specified to avoid rare race conditions with attribute discovery
35
67
  * Delays interpreting delegate until column is used
@@ -37,24 +69,28 @@ a nice looking [Changelog](http://keepachangelog.com).
37
69
  * More flexible includes. e.g.: Arrays of symbols now work
38
70
  * Raises errors for invalid `includes()` and `:uses`
39
71
 
40
- ## Version [1.1.0] <small>2019-04-23</small>
72
+ ## [1.1.0] - 2019-04-23
41
73
 
42
74
  * Add legacy types for `VirtualAttribute::Types`
43
75
  * Fix rails 5.1 bug with `includes()`
44
76
  * Remove reference to `MiqPreloader`
45
77
 
46
- ## Version [1.0.0] <small>2019-03-05</small>
78
+ ## [1.0.0] - 2019-03-05
47
79
 
48
80
  * Renamed to activerecord-virtual_attributes
49
81
  * Moved from ManageIQ to own repo
50
82
  * Added support for Rails 5.1
51
83
 
52
- ## Version 0.1.0 <small>2019-01-17</small>
84
+ ## 0.1.0 - 2019-01-17
53
85
 
54
86
  * Initial Release
55
87
  * Extracted from ManageIQ/manageiq
56
88
 
57
- [Unreleased]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v1.5.0...HEAD
89
+ [Unreleased]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v6.1.0...HEAD
90
+ [6.1.0]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v3.0.0...v6.1.0
91
+ [3.0.0]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v2.0.0...v3.0.0
92
+ [2.0.0]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v1.6.0...v2.0.0
93
+ [1.6.0]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v1.5.0...v1.6.0
58
94
  [1.5.0]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v1.4.0...v1.5.0
59
95
  [1.4.0]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v1.3.1...v1.4.0
60
96
  [1.3.1]: https://github.com/ManageIQ/activerecord-virtual_attributes/compare/v1.3.0...v1.3.1
data/Gemfile CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activerecord", "~> 5.0.7"
6
- gem "mysql2", '~> 0.4.0'
5
+ gem "activerecord", "~> 6.1.4"
6
+ gem "mysql2"
7
7
  gem "pg"
8
- gem "sqlite3", "~> 1.3.6"
8
+ gem "sqlite3"
9
9
 
10
10
  gemspec
data/README.md CHANGED
@@ -1,20 +1,16 @@
1
1
  # VirtualAttributes
2
2
 
3
- [![Build Status](https://travis-ci.org/ManageIQ/activerecord-virtual_attributes.svg?branch=master)](https://travis-ci.org/ManageIQ/activerecord-virtual_attributes)
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
- This allows you to define a ruby method that acts like an attribute or relation.
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, but you want to sort by it or filter by it.
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 attribute in sql so `ORDER BY` `WHERE` clauses will work.
11
+ This gem allows you to represent these attributes in sql so `ORDER BY` `WHERE` clauses will work.
15
12
 
16
- This gem also allows you to calculate counts, and treat those counts as a field accessible with `select(:child_count)`
17
- to get rid of the N+1 problem of running a `count(*)` on a subcollection for each row.
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.
18
14
 
19
15
  ## Installation
20
16
 
@@ -42,6 +38,11 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
42
38
 
43
39
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
44
40
 
41
+
42
+ To test with different versions of ruby, use `wwtd` gem or
43
+
44
+ DB=pg BUNDLE_GEMFILE=gemfiles/gemfile_${version-52}.gemfile bundle exec rake
45
+
45
46
  ## Contributing
46
47
 
47
48
  Bug reports and pull requests are welcome on GitHub at https://github.com/ManageIQ/activerecord-virtual_attributes .
@@ -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", ">= 5.0"
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 "rake", "~> 10.0"
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
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module VirtualAttributes
3
- VERSION = "1.5.0".freeze
3
+ VERSION = "6.1.0".freeze
4
4
  end
5
5
  end
@@ -2,14 +2,46 @@ module ActiveRecord
2
2
  module VirtualAttributes
3
3
  # VirtualArel associates arel with an attribute
4
4
  #
5
- # Model.virtual_attribute :field, :string, :arel => -> (t) { t.grouping(t[:field2]) } }
5
+ # Model.virtual_attribute :field, :string, :arel => ->(t) { t.grouping(t[:field2]) } }
6
6
  # Model.select(:field)
7
7
  #
8
8
  # is equivalent to:
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
14
+ class Arel::Nodes::Grouping
15
+ attr_accessor :name
16
+ end
17
+
12
18
  module VirtualArel
19
+ # This arel table proxy is our shim to get our functionality into rails
20
+ class ArelTableProxy < Arel::Table
21
+ attr_accessor :klass
22
+
23
+ # overrides Arel::Table#[]
24
+ # adds aliases and virtual attribute arel (aka sql)
25
+ #
26
+ # @returns Arel::Attributes::Attribute|Arel::Nodes::Grouping|Nil
27
+ # for regular database columns:
28
+ # returns an Arel::Attribute (just like Arel::Table#[])
29
+ # for virtual attributes:
30
+ # returns the arel for the value
31
+ # for non sql friendly virtual attributes:
32
+ # returns nil
33
+ def [](name, table = self)
34
+ if (col_alias = @klass.attribute_alias(name))
35
+ name = col_alias
36
+ end
37
+ if @klass.virtual_attribute?(name)
38
+ @klass.arel_for_virtual_attribute(name, table)
39
+ else
40
+ super
41
+ end
42
+ end
43
+ end
44
+
13
45
  extend ActiveSupport::Concern
14
46
 
15
47
  included do
@@ -18,17 +50,19 @@ module ActiveRecord
18
50
  end
19
51
 
20
52
  module ClassMethods
21
- def arel_attribute(column_name, arel_table = self.arel_table)
22
- load_schema
23
- if virtual_attribute?(column_name) && !attribute_alias?(column_name)
24
- col = _virtual_arel[column_name.to_s]
25
- col.call(arel_table) if col
26
- else
27
- super
53
+ if ActiveRecord.version.to_s < "6.1"
54
+ # ActiveRecord::Core 6.0 (every version of active record seems to do this differently)
55
+ def arel_table
56
+ @arel_table ||= ArelTableProxy.new(table_name, :type_caster => type_caster).tap { |t| t.klass = self }
57
+ end
58
+ else
59
+ # ActiveRecord::Core 6.1
60
+ def arel_table
61
+ @arel_table ||= ArelTableProxy.new(table_name, :klass => self)
28
62
  end
29
63
  end
30
64
 
31
- # supported by sql if
65
+ # supported by sql if any are true:
32
66
  # - it is an attribute alias
33
67
  # - it is an attribute that is non virtual
34
68
  # - it is an attribute that is virtual and has arel defined
@@ -38,9 +72,26 @@ module ActiveRecord
38
72
  (has_attribute?(name) && (!virtual_attribute?(name) || !!_virtual_arel[name.to_s]))
39
73
  end
40
74
 
75
+ # private api
76
+ #
77
+ # @return [Nil|Arel::Nodes::Grouping]
78
+ # for virtual attributes:
79
+ # returns the arel for the column
80
+ # for non sql friendly virtual attributes:
81
+ # returns nil
82
+ def arel_for_virtual_attribute(column_name, table) # :nodoc:
83
+ arel_lambda = _virtual_arel[column_name.to_s]
84
+ return unless arel_lambda
85
+
86
+ arel = arel_lambda.call(table)
87
+ arel = Arel::Nodes::Grouping.new(arel) unless arel.kind_of?(Arel::Nodes::Grouping)
88
+ arel.name = column_name
89
+ arel
90
+ end
91
+
41
92
  private
42
93
 
43
- def define_virtual_arel(name, arel)
94
+ def define_virtual_arel(name, arel) # :nodoc:
44
95
  self._virtual_arel = _virtual_arel.merge(name => arel)
45
96
  end
46
97
  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
- join_keys = if ActiveRecord.version.to_s >= "5.1"
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, join_keys.key, src_model_id, &blk)
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
- to_table = select_from_alias_table(to_ref.klass, src_model_id.relation)
251
- to_model_id = to_ref.klass.arel_attribute(to_model_col_name, to_table)
252
- to_column = to_ref.klass.arel_attribute(col, to_table)
253
- arel = query.except(:select).select(to_column).arel
254
- .from(to_table)
255
- .where(to_model_id.eq(src_model_id))
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
- Arel.sql("(#{arel.to_sql})")
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