includes_many 0.1.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 +7 -0
- data/.gitignore +24 -0
- data/.rspec +2 -0
- data/.travis.yml +14 -0
- data/Appraisals +18 -0
- data/Gemfile +14 -0
- data/LICENSE.txt +22 -0
- data/README.md +66 -0
- data/Rakefile +18 -0
- data/certs/razum2um.pem +21 -0
- data/gemfiles/.gitignore +1 -0
- data/gemfiles/rails_3_2.gemfile +14 -0
- data/gemfiles/rails_4_0.gemfile +14 -0
- data/gemfiles/rails_4_1.gemfile +14 -0
- data/gemfiles/rails_4_2.gemfile +17 -0
- data/includes_many.gemspec +30 -0
- data/lib/includes_many.rb +19 -0
- data/lib/includes_many/active_record32.rb +4 -0
- data/lib/includes_many/active_record32/association_scope.rb +93 -0
- data/lib/includes_many/active_record32/has_many.rb +43 -0
- data/lib/includes_many/active_record32/join_association.rb +37 -0
- data/lib/includes_many/active_record40.rb +4 -0
- data/lib/includes_many/active_record40/association_scope.rb +97 -0
- data/lib/includes_many/active_record40/has_many.rb +32 -0
- data/lib/includes_many/active_record40/join_association.rb +35 -0
- data/lib/includes_many/active_record41.rb +4 -0
- data/lib/includes_many/active_record41/association_scope.rb +88 -0
- data/lib/includes_many/active_record41/has_many.rb +34 -0
- data/lib/includes_many/active_record41/join_association.rb +30 -0
- data/lib/includes_many/active_record42.rb +4 -0
- data/lib/includes_many/active_record42/association_scope.rb +81 -0
- data/lib/includes_many/active_record42/has_many.rb +34 -0
- data/lib/includes_many/active_record42/join_association.rb +30 -0
- data/lib/includes_many/version.rb +3 -0
- data/spec/includes_many_spec.rb +83 -0
- data/spec/internal/app/models/comment.rb +12 -0
- data/spec/internal/config/database.yml +9 -0
- data/spec/internal/db/schema.rb +6 -0
- data/spec/internal/log/.gitkeep +0 -0
- data/spec/spec_helper.rb +26 -0
- metadata +207 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c1fd0e7ff99ce84e15556ab818ba5403422c8350
|
4
|
+
data.tar.gz: 951126e5d7da338b31b2f40cbb5b7c3e8b5e00d6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8a67bc7ad024b1b0fe1de2248fbf7c56640fa614cbedd325f19992048960adf340fe7f2b5f172ee67eb7beedb5126204b043c6baad04e6e12ee37de74679f7d3
|
7
|
+
data.tar.gz: 2c44ecf767a95989e8ca36820d51cfa6ef20cc1e2fff953caf28d493cd763eae60ca21ded30f82980b470c04319d9b5b9c3c266c2ea63b41541314bca2e30c17
|
data/.gitignore
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
23
|
+
spec/internal/db/*.sqlite3
|
24
|
+
spec/internal/log/*log
|
data/.rspec
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 1.9.3
|
4
|
+
- 2.0.0
|
5
|
+
- 2.1.1
|
6
|
+
gemfile:
|
7
|
+
- gemfiles/rails_3_2.gemfile
|
8
|
+
- gemfiles/rails_4_0.gemfile
|
9
|
+
- gemfiles/rails_4_1.gemfile
|
10
|
+
- gemfiles/rails_4_2.gemfile
|
11
|
+
matrix:
|
12
|
+
allow_failures:
|
13
|
+
- gemfile: gemfiles/rails_4_2.gemfile
|
14
|
+
|
data/Appraisals
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
appraise 'rails_3_2' do
|
2
|
+
gem 'rails', '~> 3.2.0'
|
3
|
+
end
|
4
|
+
|
5
|
+
appraise 'rails_4_0' do
|
6
|
+
gem 'rails', '~> 4.0.2'
|
7
|
+
end
|
8
|
+
|
9
|
+
appraise 'rails_4_1' do
|
10
|
+
gem 'rails', '~> 4.1.0.beta1'
|
11
|
+
end
|
12
|
+
|
13
|
+
appraise 'rails_4_2' do
|
14
|
+
gem 'rails', github: 'rails/rails', branch: 'master'
|
15
|
+
gem 'arel', github: 'rails/arel', branch: 'master'
|
16
|
+
gem 'rack', github: 'rack/rack', branch: 'master'
|
17
|
+
gem 'i18n', github: 'svenfuchs/i18n', branch: 'master'
|
18
|
+
end
|
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in includes_many.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :development do
|
7
|
+
# tools
|
8
|
+
gem 'debugger', github: 'razum2um/debugger'
|
9
|
+
gem 'pry-debugger'
|
10
|
+
gem 'pry-stack_explorer'
|
11
|
+
# rspec --format fuubar
|
12
|
+
gem 'fuubar', github: 'thekompanee/fuubar'
|
13
|
+
end
|
14
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Vlad Bokov
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# IncludesMany
|
2
|
+
|
3
|
+
[![Gem Version][GV img]][Gem Version]
|
4
|
+
[![Build Status][BS img]][Build Status]
|
5
|
+
|
6
|
+
This implements [rails/rails#16277](https://github.com/rails/rails/pull/16277) as a Gem.
|
7
|
+
Tested with Rails 3.2.19, 4.0.8, 4.1.4 :)
|
8
|
+
|
9
|
+
Sad, but ActiveRecord is hard to extend :( I used monkeypatch,
|
10
|
+
but it's protected by [`safe_monkeypatch`](https://github.com/razum2um/safe_monkeypatch)
|
11
|
+
It will loudly complain at startup time if it's incompatible. Feel free to open an issue if such.
|
12
|
+
|
13
|
+
Use it and upgrade without fear!
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
Use `includes_many` in your AR-model:
|
18
|
+
|
19
|
+
includes_many :siblings_and_children, :class_name => 'Comment',
|
20
|
+
:foreign_key => :parent_id, :primary_key => proc { |c| [c.parent_id, c.id] }
|
21
|
+
|
22
|
+
And do eager loading:
|
23
|
+
|
24
|
+
comments = Comment.where(body: 'something').includes(:siblings_and_children)
|
25
|
+
comments.map(&:siblings_and_children) # ...
|
26
|
+
|
27
|
+
This would issue only 2 SQL queries just as expected.
|
28
|
+
|
29
|
+
Normally, without this gem you would write an instance method `siblings_and_children`
|
30
|
+
and calling a method would end up with an N+1 problem.
|
31
|
+
|
32
|
+
## Installation
|
33
|
+
|
34
|
+
Add my public key:
|
35
|
+
|
36
|
+
gem cert --add <(curl -Ls https://raw.github.com/razum2um/include_many/master/certs/razum2um.pem)
|
37
|
+
|
38
|
+
$ gem install include_many # without key
|
39
|
+
$ gem install include_many -P HighSecurity # secure, with key added
|
40
|
+
|
41
|
+
Add this line to your application's Gemfile:
|
42
|
+
|
43
|
+
gem 'includes_many'
|
44
|
+
|
45
|
+
## Contributing
|
46
|
+
|
47
|
+
To test under different Rails version use [`appraisal`](https://github.com/thoughtbot/appraisal)
|
48
|
+
To experiment inside a console:
|
49
|
+
|
50
|
+
appraisal rails_3_2 rake c # etc..
|
51
|
+
|
52
|
+
1. Fork it ( https://github.com/razum2um/includes_many/fork )
|
53
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
54
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
55
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
56
|
+
5. Create a new Pull Request
|
57
|
+
|
58
|
+
## Acknoledgements
|
59
|
+
|
60
|
+
Thanks for [@pat](https://github.com/pat) for `combustion` and multi-rails testing practices.
|
61
|
+
|
62
|
+
[Gem Version]: https://rubygems.org/gems/includes_many
|
63
|
+
[Build Status]: https://travis-ci.org/razum2um/includes_many
|
64
|
+
|
65
|
+
[GV img]: https://badge.fury.io/rb/includes_many.png
|
66
|
+
[BS img]: https://travis-ci.org/razum2um/includes_many.png
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
|
5
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
6
|
+
t.rspec_opts = "--format progress"
|
7
|
+
end
|
8
|
+
|
9
|
+
desc 'pry console for gem'
|
10
|
+
task :c do
|
11
|
+
require 'pry'
|
12
|
+
require 'includes_many'
|
13
|
+
ARGV.clear
|
14
|
+
Pry.start
|
15
|
+
end
|
16
|
+
|
17
|
+
task :default => [:spec]
|
18
|
+
|
data/certs/razum2um.pem
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDeDCCAmCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBBMRMwEQYDVQQDDApib2tv
|
3
|
+
di52bGFkMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZFgNj
|
4
|
+
b20wHhcNMTQwNTIwMjAyOTAyWhcNMTUwNTIwMjAyOTAyWjBBMRMwEQYDVQQDDApi
|
5
|
+
b2tvdi52bGFkMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZ
|
6
|
+
FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCibrb/aiZX3kWo
|
7
|
+
Fmzo3gvGBFS9N18Q5rp9UTJRc4KxZQOay2WcgLjy1oU61r2Urjz3VDT4sg/yw3N3
|
8
|
+
YXIPqSTRl+OPIaafe45TVpF4mtMSsc1Gm/O3Sfoz6URiMd9iDtc2sTpaMgatL4pV
|
9
|
+
EExER9emjrmElRFknJD65E3gVDX7KXvrZYYAScJR33DADIGUgpuyHm29S7G/4WAy
|
10
|
+
ol6XfmPx+x5rM49QytGSNCQDYQ3SMMCo9wKkEm3Zcx0O4qhO8INevl/mvkAWLhOA
|
11
|
+
+0qldtuUx9wbBQ0D0wVR8LTafqWrIUHQjWXqrhWBqXhYeR3jj5aehBhpPFclHuKU
|
12
|
+
5GeILZrFAgMBAAGjezB5MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
|
13
|
+
BBSiidH2CEJmkza+NBBJNLcnzQX57TAfBgNVHREEGDAWgRRib2tvdi52bGFkQGdt
|
14
|
+
YWlsLmNvbTAfBgNVHRIEGDAWgRRib2tvdi52bGFkQGdtYWlsLmNvbTANBgkqhkiG
|
15
|
+
9w0BAQUFAAOCAQEAVEyF63kQT9HKm3YIw1WzLvuOMvEUThzBomMMsTp9CGXWvem6
|
16
|
+
wZdMhxykwk1lga0OwsCn+wr1tWZ/cNeWqGSY00vTfLWdriK60xuRW7zT1Z5tmxbD
|
17
|
+
dq2ULdhII/qCFQlzDB/+IptO1rJLzfxTckoArmeYtkBV6LaVd7wpaRZnw0Apm93e
|
18
|
+
ph03YddPDbB34xTivvu4d6BBbKGxj/YN+1NLD9rMi6FspgcA4P1UlmKqyCluTbZj
|
19
|
+
vzKbYclpJ7gENr/xiTjGqA/Md3zJMzmsFrzUXt4RVmo5SaCyZjC6gFfhSr+PODc7
|
20
|
+
ZaSbckvH/+m4boAsg0JkGGFcS3j5fgNmdwgA1A==
|
21
|
+
-----END CERTIFICATE-----
|
data/gemfiles/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.gemfile.lock
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "rails", "~> 3.2.0"
|
6
|
+
|
7
|
+
group :development do
|
8
|
+
gem "debugger", :github => "razum2um/debugger"
|
9
|
+
gem "pry-debugger"
|
10
|
+
gem "pry-stack_explorer"
|
11
|
+
gem "fuubar", :github => "thekompanee/fuubar"
|
12
|
+
end
|
13
|
+
|
14
|
+
gemspec :path => "../"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "rails", "~> 4.0.2"
|
6
|
+
|
7
|
+
group :development do
|
8
|
+
gem "debugger", :github => "razum2um/debugger"
|
9
|
+
gem "pry-debugger"
|
10
|
+
gem "pry-stack_explorer"
|
11
|
+
gem "fuubar", :github => "thekompanee/fuubar"
|
12
|
+
end
|
13
|
+
|
14
|
+
gemspec :path => "../"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "rails", "~> 4.1.0.beta1"
|
6
|
+
|
7
|
+
group :development do
|
8
|
+
gem "debugger", :github => "razum2um/debugger"
|
9
|
+
gem "pry-debugger"
|
10
|
+
gem "pry-stack_explorer"
|
11
|
+
gem "fuubar", :github => "thekompanee/fuubar"
|
12
|
+
end
|
13
|
+
|
14
|
+
gemspec :path => "../"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# This file was generated by Appraisal
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
gem "rails", :github => "rails/rails", :branch => "master"
|
6
|
+
gem "arel", :github => "rails/arel", :branch => "master"
|
7
|
+
gem "rack", :github => "rack/rack", :branch => "master"
|
8
|
+
gem "i18n", :github => "svenfuchs/i18n", :branch => "master"
|
9
|
+
|
10
|
+
group :development do
|
11
|
+
gem "debugger", :github => "razum2um/debugger"
|
12
|
+
gem "pry-debugger"
|
13
|
+
gem "pry-stack_explorer"
|
14
|
+
gem "fuubar", :github => "thekompanee/fuubar"
|
15
|
+
end
|
16
|
+
|
17
|
+
gemspec :path => "../"
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'includes_many/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "includes_many"
|
8
|
+
spec.version = IncludesMany::VERSION
|
9
|
+
spec.authors = ["Vlad Bokov"]
|
10
|
+
spec.email = ["razum2um@mail.ru"]
|
11
|
+
spec.summary = %q{ActiveRecord has_many + includes(:relation) on steroids}
|
12
|
+
spec.description = %q{ActiveRecord has_many + includes(:relation) on steroids}
|
13
|
+
spec.homepage = "https://github.com/razum2um/include_many"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "activerecord", ">= 3.2", "< 4.2"
|
22
|
+
spec.add_dependency "safe_monkeypatch", "~> 0.1"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
25
|
+
spec.add_development_dependency "sqlite3"
|
26
|
+
spec.add_development_dependency "rspec"
|
27
|
+
spec.add_development_dependency "rake"
|
28
|
+
spec.add_development_dependency "combustion"
|
29
|
+
spec.add_development_dependency "appraisal"
|
30
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "includes_many/version"
|
2
|
+
require "safe_monkeypatch"
|
3
|
+
require "active_record"
|
4
|
+
|
5
|
+
major, minor, _ = Gem::Version.new(ActiveRecord::VERSION::STRING).segments
|
6
|
+
require "includes_many/active_record#{major}#{minor}"
|
7
|
+
|
8
|
+
module IncludesMany
|
9
|
+
end
|
10
|
+
|
11
|
+
module ActiveRecord
|
12
|
+
module Associations
|
13
|
+
module ClassMethods
|
14
|
+
module_eval do
|
15
|
+
alias includes_many has_many
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Associations
|
3
|
+
class AssociationScope
|
4
|
+
safe_monkeypatch :add_constraints, md5: '9c737355ac54b790c3e6b9c5feb37513'
|
5
|
+
|
6
|
+
def add_constraints(scope)
|
7
|
+
tables = construct_tables
|
8
|
+
|
9
|
+
chain.each_with_index do |reflection, i|
|
10
|
+
table, foreign_table = tables.shift, tables.first
|
11
|
+
|
12
|
+
if reflection.source_macro == :has_and_belongs_to_many
|
13
|
+
join_table = tables.shift
|
14
|
+
|
15
|
+
scope = scope.joins(join(
|
16
|
+
join_table,
|
17
|
+
table[reflection.association_primary_key].
|
18
|
+
eq(join_table[reflection.association_foreign_key])
|
19
|
+
))
|
20
|
+
|
21
|
+
table, foreign_table = join_table, tables.first
|
22
|
+
end
|
23
|
+
|
24
|
+
if reflection.source_macro == :belongs_to
|
25
|
+
if reflection.options[:polymorphic]
|
26
|
+
key = reflection.association_primary_key(klass)
|
27
|
+
else
|
28
|
+
key = reflection.association_primary_key
|
29
|
+
end
|
30
|
+
|
31
|
+
foreign_key = reflection.foreign_key
|
32
|
+
else
|
33
|
+
key = reflection.foreign_key
|
34
|
+
foreign_key = reflection.active_record_primary_key
|
35
|
+
end
|
36
|
+
|
37
|
+
conditions = self.conditions[i]
|
38
|
+
|
39
|
+
# PATCH here
|
40
|
+
if key.respond_to?(:call)
|
41
|
+
key = key.call(owner)
|
42
|
+
end
|
43
|
+
# end PATCH
|
44
|
+
|
45
|
+
if reflection == chain.last
|
46
|
+
# PATCH here
|
47
|
+
fk_arel = if foreign_key.respond_to?(:call)
|
48
|
+
fk = foreign_key.call(owner)
|
49
|
+
if fk.respond_to?(:each)
|
50
|
+
table[key].in(fk.compact)
|
51
|
+
else
|
52
|
+
table[key].eq(fk)
|
53
|
+
end
|
54
|
+
else
|
55
|
+
table[key].eq(owner[foreign_key])
|
56
|
+
end
|
57
|
+
scope = scope.where(fk_arel)
|
58
|
+
# end PATCH
|
59
|
+
|
60
|
+
if reflection.type
|
61
|
+
scope = scope.where(table[reflection.type].eq(owner.class.base_class.name))
|
62
|
+
end
|
63
|
+
|
64
|
+
conditions.each do |condition|
|
65
|
+
if options[:through] && condition.is_a?(Hash)
|
66
|
+
condition = disambiguate_condition(table, condition)
|
67
|
+
end
|
68
|
+
|
69
|
+
scope = scope.where(interpolate(condition))
|
70
|
+
end
|
71
|
+
else
|
72
|
+
constraint = table[key].eq(foreign_table[foreign_key])
|
73
|
+
|
74
|
+
if reflection.type
|
75
|
+
type = chain[i + 1].klass.base_class.name
|
76
|
+
constraint = constraint.and(table[reflection.type].eq(type))
|
77
|
+
end
|
78
|
+
|
79
|
+
scope = scope.joins(join(foreign_table, constraint))
|
80
|
+
|
81
|
+
unless conditions.empty?
|
82
|
+
scope = scope.where(sanitize(conditions, table))
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
scope
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module Associations
|
3
|
+
class Preloader
|
4
|
+
class HasMany
|
5
|
+
safe_monkeypatch :association_key_name, md5: 'c4a2d2c69f85b007bf546989d601b94a'
|
6
|
+
|
7
|
+
# method is fully rewritten
|
8
|
+
def association_key_name
|
9
|
+
fk = reflection.foreign_key
|
10
|
+
if fk.respond_to?(:call)
|
11
|
+
fk.call(owners.first)
|
12
|
+
else
|
13
|
+
fk
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
safe_monkeypatch :owners_by_key, md5: '33eab3037fd994d4a7106a68a05f169d'
|
18
|
+
|
19
|
+
# method is fully rewritten
|
20
|
+
def owners_by_key
|
21
|
+
@owners_by_key ||= begin
|
22
|
+
res = Hash.new { |h,k| h[k] = Set.new }
|
23
|
+
owners.each do |owner|
|
24
|
+
key = if owner_key_name.respond_to?(:call)
|
25
|
+
owner_key_name.call(owner)
|
26
|
+
else
|
27
|
+
owner[owner_key_name]
|
28
|
+
end
|
29
|
+
|
30
|
+
if key.respond_to?(:each)
|
31
|
+
key.each { |k| res[k && k.to_s] << owner }
|
32
|
+
else
|
33
|
+
res[key && key.to_s] << owner
|
34
|
+
end
|
35
|
+
end
|
36
|
+
res
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|