blueprinter-activerecord 1.0.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/lib/blueprinter-activerecord/added_preloads_logger.rb +52 -0
- data/lib/blueprinter-activerecord/helpers.rb +74 -0
- data/lib/blueprinter-activerecord/missing_preloads_logger.rb +49 -0
- data/lib/blueprinter-activerecord/preload_info.rb +57 -0
- data/lib/blueprinter-activerecord/preloader.rb +80 -0
- data/lib/blueprinter-activerecord/query_methods.rb +69 -0
- data/lib/blueprinter-activerecord/railtie.rb +7 -0
- data/lib/blueprinter-activerecord/version.rb +5 -0
- data/lib/blueprinter-activerecord.rb +19 -0
- data/lib/tasks/blueprinter_activerecord.rake +21 -0
- metadata +162 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 65c4c6d27e0bea2ed2d73f35949587cf6f2197cd540fe2a1ceef1a49d2d135d8
|
4
|
+
data.tar.gz: 850d61584f87c743478d496ce1117cdd2bda7b6db7d92a582cb875f7d63c4f70
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 40c750e1e67710a3e695a495be6702393f6f72f145ebf47cc21d78587c34cb14ae899edb4cb76a31c599bdb075b5f93c490ff7eb7f5ddc9d16bf15e22314f544
|
7
|
+
data.tar.gz: 531d150f3cc8aa474d8c149ae35663395cf0893e406953cf0174cd06fc77ff92f8c7c1cd4ccbaa63a054b7ba930fcb92efd4bf501c6323e1f6033d8a40787053
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BlueprinterActiveRecord
|
4
|
+
#
|
5
|
+
# A Blueprinter extension to log what preloads were found and added by the BlueprinterActiveRecord::Preloader extension.
|
6
|
+
#
|
7
|
+
# This extension may safely be used alongside the BlueprinterActiveRecord::MissingPreloadsLogger extension. Each query will
|
8
|
+
# only be processed by one.
|
9
|
+
#
|
10
|
+
# NOTE Only queries that pass through a Blueprint's "render" method will be found.
|
11
|
+
#
|
12
|
+
# Blueprinter.configure do |config|
|
13
|
+
# # The Preloader extension MUST be added first!
|
14
|
+
# config.extensions << BlueprinterActiveRecord::Preloader.new
|
15
|
+
#
|
16
|
+
# config.extensions << BlueprinterActiveRecord::AddedPreloadsLogger.new do |info|
|
17
|
+
# next unless info.found.any?
|
18
|
+
#
|
19
|
+
# Rails.logger.info({
|
20
|
+
# event: "added_preloads",
|
21
|
+
# root_model: info.query.model.name,
|
22
|
+
# sql: info.query.to_sql,
|
23
|
+
# added: info.found.map { |x| x.join " > " },
|
24
|
+
# percent_added: info.percent_found,
|
25
|
+
# trace: info.trace,
|
26
|
+
# }.to_json)
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
class AddedPreloadsLogger < Blueprinter::Extension
|
31
|
+
include Helpers
|
32
|
+
|
33
|
+
#
|
34
|
+
# Initialize and configure the extension.
|
35
|
+
#
|
36
|
+
# @yield [BlueprinterActiveRecord::PreloadInfo] Your logging action
|
37
|
+
#
|
38
|
+
def initialize(&log_proc)
|
39
|
+
@log_proc = log_proc
|
40
|
+
end
|
41
|
+
|
42
|
+
def pre_render(object, blueprint, view, options)
|
43
|
+
if object.is_a?(ActiveRecord::Relation) && object.before_preload_blueprint
|
44
|
+
from_code = object.before_preload_blueprint
|
45
|
+
from_blueprint = Preloader.preloads(blueprint, view, object.model)
|
46
|
+
info = PreloadInfo.new(object, from_code, from_blueprint, caller)
|
47
|
+
@log_proc&.call(info)
|
48
|
+
end
|
49
|
+
object
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BlueprinterActiveRecord
|
4
|
+
module Helpers
|
5
|
+
extend self
|
6
|
+
|
7
|
+
#
|
8
|
+
# Combines all types of preloads (preload, includes, eager_load) into a single nested hash
|
9
|
+
#
|
10
|
+
# @param q [ActiveRecord::Relation]
|
11
|
+
# @return [Hash] Symbol keys with Hash values of arbitrary depth
|
12
|
+
#
|
13
|
+
def extract_preloads(q)
|
14
|
+
merge_values [*q.values[:preload], *q.values[:includes], *q.values[:eager_load]]
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# Count the number of preloads in a nested Hash.
|
19
|
+
#
|
20
|
+
# @param preloads [Hash] Nested Hash of preloads
|
21
|
+
# @return [Integer] The number of associations in the Hash
|
22
|
+
#
|
23
|
+
def count_preloads(preloads)
|
24
|
+
preloads.reduce(0) { |acc, (_key, val)|
|
25
|
+
acc + 1 + count_preloads(val)
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# Finds preloads from 'after' that are missing in 'before'.
|
31
|
+
#
|
32
|
+
# @param before [Hash] The extracted preloads from before Preloader ran
|
33
|
+
# @param after [Hash] The extracted preloads from after Preloader ran
|
34
|
+
# @param diff [Array<BlueprinterActiveRecord::MissingPreload>] internal use
|
35
|
+
# @param path [Array<Symbol>] internal use
|
36
|
+
# @return [Array<Array<Symbol>>] the preloads missing from 'before' . They're in a "path" structure, with the last element of each sub-array being the missing preload, e.g. `[[:widget], [:project, :company]]`
|
37
|
+
#
|
38
|
+
def diff_preloads(before, after, diff = [], path = [])
|
39
|
+
after.each_with_object(diff) do |(key, after_val), obj|
|
40
|
+
sub_path = path + [key]
|
41
|
+
before_val = before[key]
|
42
|
+
obj << sub_path if before_val.nil?
|
43
|
+
diff_preloads(before_val || {}, after_val, diff, sub_path)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Merges 'values', which may be any nested structure of arrays, hashes, strings, and symbols into a nested hash.
|
49
|
+
#
|
50
|
+
# @param value [Array|Hash|String|Symbol]
|
51
|
+
# @param result [Hash]
|
52
|
+
# @return [Hash] Symbol keys with Hash values of arbitrary depth
|
53
|
+
#
|
54
|
+
def merge_values(value, result = {})
|
55
|
+
case value
|
56
|
+
when Array
|
57
|
+
value.each { |val| merge_values(val, result) }
|
58
|
+
when Hash
|
59
|
+
value.each { |key, val|
|
60
|
+
key = key.to_sym
|
61
|
+
result[key] ||= {}
|
62
|
+
merge_values(val, result[key])
|
63
|
+
}
|
64
|
+
when Symbol
|
65
|
+
result[value] ||= {}
|
66
|
+
when String
|
67
|
+
result[value.to_sym] ||= {}
|
68
|
+
else
|
69
|
+
raise ArgumentError, "Unexpected value of type '#{value.class.name}' (#{value.inspect})"
|
70
|
+
end
|
71
|
+
result
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BlueprinterActiveRecord
|
4
|
+
#
|
5
|
+
# A Blueprinter extension to log what COULD have been preloaded with the BlueprinterActiveRecord::Preloader extension.
|
6
|
+
#
|
7
|
+
# This extension may safely be used alongside the BlueprinterActiveRecord::Preloader and BlueprinterActiveRecord::AddedPreloadsLogger
|
8
|
+
# extensions. Any queries processed by those extensions will be ignored by this one.
|
9
|
+
#
|
10
|
+
# NOTE Only queries that pass through a Blueprint's "render" method will be found.
|
11
|
+
#
|
12
|
+
# Blueprinter.configure do |config|
|
13
|
+
# config.extensions << BlueprinterActiveRecord::MissingPreloadsLogger.new do |info|
|
14
|
+
# next unless info.found.any?
|
15
|
+
#
|
16
|
+
# Rails.logger.info({
|
17
|
+
# event: "missing_preloads",
|
18
|
+
# root_model: info.query.model.name,
|
19
|
+
# sql: info.query.to_sql,
|
20
|
+
# missing: info.found.map { |x| x.join " > " },
|
21
|
+
# percent_missing: info.percent_found,
|
22
|
+
# trace: info.trace,
|
23
|
+
# }.to_json)
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
class MissingPreloadsLogger < Blueprinter::Extension
|
28
|
+
include Helpers
|
29
|
+
|
30
|
+
#
|
31
|
+
# Initialize and configure the extension.
|
32
|
+
#
|
33
|
+
# @yield [BlueprinterActiveRecord::PreloadInfo] Your logging action
|
34
|
+
#
|
35
|
+
def initialize(&log_proc)
|
36
|
+
@log_proc = log_proc
|
37
|
+
end
|
38
|
+
|
39
|
+
def pre_render(object, blueprint, view, options)
|
40
|
+
if object.is_a?(ActiveRecord::Relation) && !object.before_preload_blueprint
|
41
|
+
from_code = extract_preloads object
|
42
|
+
from_blueprint = Preloader.preloads(blueprint, view, object.model)
|
43
|
+
info = PreloadInfo.new(object, from_code, from_blueprint, caller)
|
44
|
+
@log_proc&.call(info)
|
45
|
+
end
|
46
|
+
object
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BlueprinterActiveRecord
|
4
|
+
#
|
5
|
+
# Info about preloads from a query that was run through a Blueprinter's render method.
|
6
|
+
#
|
7
|
+
# Used for logging by the BlueprinterActiveRecord::MissingPreloadsLogger and BlueprinterActiveRecord::AddedPreloadsLogger extensions.
|
8
|
+
#
|
9
|
+
class PreloadInfo
|
10
|
+
include Helpers
|
11
|
+
|
12
|
+
# @return [ActiveRecord::Relation] The base query
|
13
|
+
attr_reader :query
|
14
|
+
|
15
|
+
# @return [Array<String>] Stack trace to the query
|
16
|
+
attr_reader :trace
|
17
|
+
|
18
|
+
#
|
19
|
+
# @param query [ActiveRecord::Relation] The query passed to "render"
|
20
|
+
# @param from_code [Hash] Nested Hash of preloads, includes, and eager_loads that were present in query when passed to "render"
|
21
|
+
# @param from_blueprint [Hash] Nested Hash of associations pulled from the Blueprint view
|
22
|
+
# @param trace [Array<String>] Stack trace to query
|
23
|
+
#
|
24
|
+
def initialize(query, from_code, from_blueprint, trace)
|
25
|
+
@query = query
|
26
|
+
@from_code = from_code
|
27
|
+
@from_blueprint = from_blueprint
|
28
|
+
@trace = trace
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [Integer] The percent of total preloads found by BlueprinterActiveRecord
|
32
|
+
def percent_found
|
33
|
+
total = num_existing + found.size
|
34
|
+
((found.size / num_existing.to_f) * 100).round
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [Integer] The number of preloads, includes, and eager_loads that existed before BlueprinterActiveRecord was involved
|
38
|
+
def num_existing
|
39
|
+
@num_existing ||= count_preloads(hash)
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [Array<Array<Symbol>>] Array of "preload paths" (e.g. [[:project, :company]]) to missing preloads that could have been found & added by BlueprinterActiveRecord::Preloader
|
43
|
+
def found
|
44
|
+
@found ||= diff_preloads(@from_code, hash)
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [Array<Array<Symbol>>] Array of "preload paths" (e.g. [[:project, :company]]) from the blueprint that were visible to the preloader
|
48
|
+
def visible
|
49
|
+
@visible ||= diff_preloads({}, @from_blueprint)
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [Hash] Nested hash of all preloads, both manually added and auto found
|
53
|
+
def hash
|
54
|
+
@hash ||= merge_values [@from_code, @from_blueprint]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BlueprinterActiveRecord
|
4
|
+
# A Blueprinter extension to automatically preload a Blueprint view's ActiveRecord associations during render
|
5
|
+
class Preloader < Blueprinter::Extension
|
6
|
+
include Helpers
|
7
|
+
|
8
|
+
attr_reader :use, :auto, :auto_proc
|
9
|
+
|
10
|
+
#
|
11
|
+
# Initialize and configure the extension.
|
12
|
+
#
|
13
|
+
# @param auto [true|false] When true, preload for EVERY ActiveRecord::Relation passed to a Blueprint
|
14
|
+
# @param use [:preload|:includes] When `auto` is true, use this method (e.g. :preload) for preloading
|
15
|
+
# @yield [Object, Class, Symbol, Hash] Instead of passing `auto` as a boolean, you may define a block that accepts the object to render, the blueprint class, the view, and options. If the block returns true, auto preloading will take place.
|
16
|
+
#
|
17
|
+
def initialize(auto: false, use: :preload, &auto_proc)
|
18
|
+
@auto = auto
|
19
|
+
@auto_proc = auto_proc
|
20
|
+
@use =
|
21
|
+
case use
|
22
|
+
when :preload, :includes
|
23
|
+
use
|
24
|
+
else
|
25
|
+
raise ArgumentError, "Unknown value '#{use.inspect}' for `BlueprinterActiveRecord::Preloader` argument 'use'. Valid values are :preload, :includes."
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# Implements the "pre_render" Blueprinter Extension to preload associations from a view.
|
31
|
+
# If auto is true, all ActiveRecord::Relation objects will be preloaded. If auto is false,
|
32
|
+
# only queries that have called `.preload_blueprint` will be preloaded.
|
33
|
+
#
|
34
|
+
# NOTE: If auto is on, *don't* be concerned that you'll end up with duplicate preloads. Even if
|
35
|
+
# the query ends up with overlapping members in 'preload' and 'includes', ActiveRecord
|
36
|
+
# intelligently handles them. There are several unit tests which confirm this behavior.
|
37
|
+
#
|
38
|
+
def pre_render(object, blueprint, view, options)
|
39
|
+
case object
|
40
|
+
when ActiveRecord::Relation
|
41
|
+
if object.preload_blueprint_method || auto || auto_proc&.call(object, blueprint, view, options) == true
|
42
|
+
object.before_preload_blueprint = extract_preloads object
|
43
|
+
blueprint_preloads = self.class.preloads(blueprint, view, object.model)
|
44
|
+
loader = object.preload_blueprint_method || use
|
45
|
+
object.public_send(loader, blueprint_preloads)
|
46
|
+
else
|
47
|
+
object
|
48
|
+
end
|
49
|
+
else
|
50
|
+
object
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
#
|
57
|
+
# Returns an ActiveRecord preload plan extracted from the Blueprint and view (recursive).
|
58
|
+
#
|
59
|
+
# Example:
|
60
|
+
#
|
61
|
+
# preloads = BlueprinterActiveRecord::Preloader.preloads(WidgetBlueprint, :extended, Widget)
|
62
|
+
# q = Widget.where(...).order(...).preload(preloads)
|
63
|
+
#
|
64
|
+
# @param blueprint [Class] The Blueprint class
|
65
|
+
# @param view_name [Symbol] Name of the view in blueprint
|
66
|
+
# @param model [Class] The ActiveRecord model class that blueprint represents
|
67
|
+
# @return [Hash] A Hash containing preload/eager_load/etc info for ActiveRecord
|
68
|
+
#
|
69
|
+
def self.preloads(blueprint, view_name, model=nil)
|
70
|
+
view = blueprint.reflections.fetch(view_name)
|
71
|
+
view.associations.each_with_object({}) { |(_name, assoc), acc|
|
72
|
+
ref = model ? model.reflections[assoc.name.to_s] : nil
|
73
|
+
if (ref || model.nil?) && !assoc.blueprint.is_a?(Proc)
|
74
|
+
ref_model = ref && !(ref.belongs_to? && ref.polymorphic?) ? ref.klass : nil
|
75
|
+
acc[assoc.name] = preloads(assoc.blueprint, assoc.view, ref_model)
|
76
|
+
end
|
77
|
+
}
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module BlueprinterActiveRecord
|
4
|
+
module QueryMethods
|
5
|
+
module Delegates
|
6
|
+
def preload_blueprint(blueprint = nil, view = :default, use: :preload)
|
7
|
+
all.preload_blueprint(blueprint, view, use: use)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
ACTIONS = %i(preload eager_load includes).freeze
|
12
|
+
|
13
|
+
#
|
14
|
+
# Automatically preload (or `eager_load` or `includes`) the associations in the given
|
15
|
+
# blueprint and view (recursively).
|
16
|
+
#
|
17
|
+
# You can have the Blueprint and view autodetected on render:
|
18
|
+
#
|
19
|
+
# q = Widget.where(...).preload_blueprint
|
20
|
+
# WidgetBlueprint.render(q, view: :extended)
|
21
|
+
#
|
22
|
+
# Or you can pass them up front:
|
23
|
+
#
|
24
|
+
# widgets = Widget.where(...).preload_blueprint(WidgetBlueprint, :extended).to_a
|
25
|
+
# # do something with widgets, then render
|
26
|
+
# WidgetBlueprint.render(widgets, view: :extended)
|
27
|
+
#
|
28
|
+
# @param blueprint [Class] The Blueprinter class to use (ignore to autodetect on render)
|
29
|
+
# @param view [Symbol] The Blueprinter view name to use (ignore to autodetect on render)
|
30
|
+
# @param use [Symbol] The eager loading strategy to use (:preload, :includes, :eager_load)
|
31
|
+
# @return [ActiveRecord::Relation]
|
32
|
+
#
|
33
|
+
def preload_blueprint(blueprint = nil, view = :default, use: :preload)
|
34
|
+
spawn.preload_blueprint!(blueprint, view, use: use)
|
35
|
+
end
|
36
|
+
|
37
|
+
# See preload_blueprint
|
38
|
+
def preload_blueprint!(blueprint = nil, view = :default, use: :preload)
|
39
|
+
unless ACTIONS.include? use
|
40
|
+
valid = ACTIONS.map(&:inspect).join(", ")
|
41
|
+
raise BlueprinterError, "Unknown `preload_blueprint` method :#{use}. Valid methods are #{valid}."
|
42
|
+
end
|
43
|
+
|
44
|
+
if blueprint and view
|
45
|
+
# preload right now
|
46
|
+
preloads = Preloader.preloads(blueprint, view, model)
|
47
|
+
public_send(use, preloads)
|
48
|
+
else
|
49
|
+
# preload during render
|
50
|
+
@values[:preload_blueprint_method] = use
|
51
|
+
self
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def preload_blueprint_method
|
56
|
+
@values[:preload_blueprint_method]
|
57
|
+
end
|
58
|
+
|
59
|
+
# Get the preloads present before the Preloader extension ran (internal, for PreloadLogger)
|
60
|
+
def before_preload_blueprint
|
61
|
+
@values[:before_preload_blueprint]
|
62
|
+
end
|
63
|
+
|
64
|
+
# Set the preloads present before the Preloader extension ran (internal, for PreloadLogger)
|
65
|
+
def before_preload_blueprint=(val)
|
66
|
+
@values[:before_preload_blueprint] = val
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'blueprinter'
|
4
|
+
require 'active_record'
|
5
|
+
|
6
|
+
module BlueprinterActiveRecord
|
7
|
+
autoload :QueryMethods, 'blueprinter-activerecord/query_methods'
|
8
|
+
autoload :Preloader, 'blueprinter-activerecord/preloader'
|
9
|
+
autoload :AddedPreloadsLogger, 'blueprinter-activerecord/added_preloads_logger'
|
10
|
+
autoload :MissingPreloadsLogger, 'blueprinter-activerecord/missing_preloads_logger'
|
11
|
+
autoload :PreloadInfo, 'blueprinter-activerecord/preload_info'
|
12
|
+
autoload :Helpers, 'blueprinter-activerecord/helpers'
|
13
|
+
autoload :Version, 'blueprinter-activerecord/version'
|
14
|
+
end
|
15
|
+
|
16
|
+
ActiveRecord::Relation.send(:include, BlueprinterActiveRecord::QueryMethods)
|
17
|
+
ActiveRecord::Base.extend(BlueprinterActiveRecord::QueryMethods::Delegates)
|
18
|
+
|
19
|
+
require 'blueprinter-activerecord/railtie' if defined? Rails::Railtie
|
@@ -0,0 +1,21 @@
|
|
1
|
+
namespace :blueprinter do
|
2
|
+
namespace :activerecord do
|
3
|
+
desc "Prints the preload plan"
|
4
|
+
task :preloads, [:blueprint, :view, :model] => :environment do |_, args|
|
5
|
+
def pretty(hash, indent = 0)
|
6
|
+
s = " " * indent
|
7
|
+
buff = "{"
|
8
|
+
hash.each { |key, val|
|
9
|
+
buff << "\n#{s} :#{key} => #{pretty val, indent + 2},"
|
10
|
+
}
|
11
|
+
buff << "\n#{s}" if hash.any?
|
12
|
+
buff << "}"
|
13
|
+
end
|
14
|
+
|
15
|
+
model = args[:model].constantize
|
16
|
+
blueprint = args[:blueprint].constantize
|
17
|
+
preloads = BlueprinterActiveRecord::Preloader.preloads(blueprint, args[:view].to_sym, model)
|
18
|
+
puts pretty preloads
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: blueprinter-activerecord
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Procore Technologies, Inc.
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-02-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activerecord
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '6.0'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '7.2'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '6.0'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '7.2'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: blueprinter
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.0'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '1.0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: appraisal
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '2.5'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '2.5'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: database_cleaner
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '2.0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '2.0'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: minitest
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '5.0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '5.0'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: rake
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '13.0'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '13.0'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: sqlite3
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '1.4'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "~>"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '1.4'
|
117
|
+
description: Eager loading and other ActiveRecord helpers for Blueprinter
|
118
|
+
email:
|
119
|
+
- opensource@procore.com
|
120
|
+
executables: []
|
121
|
+
extensions: []
|
122
|
+
extra_rdoc_files: []
|
123
|
+
files:
|
124
|
+
- lib/blueprinter-activerecord.rb
|
125
|
+
- lib/blueprinter-activerecord/added_preloads_logger.rb
|
126
|
+
- lib/blueprinter-activerecord/helpers.rb
|
127
|
+
- lib/blueprinter-activerecord/missing_preloads_logger.rb
|
128
|
+
- lib/blueprinter-activerecord/preload_info.rb
|
129
|
+
- lib/blueprinter-activerecord/preloader.rb
|
130
|
+
- lib/blueprinter-activerecord/query_methods.rb
|
131
|
+
- lib/blueprinter-activerecord/railtie.rb
|
132
|
+
- lib/blueprinter-activerecord/version.rb
|
133
|
+
- lib/tasks/blueprinter_activerecord.rake
|
134
|
+
homepage: https://github.com/procore-oss/blueprinter-activerecord
|
135
|
+
licenses:
|
136
|
+
- MIT
|
137
|
+
metadata:
|
138
|
+
homepage_uri: https://github.com/procore-oss/blueprinter-activerecord
|
139
|
+
source_code_uri: https://github.com/procore-oss/blueprinter-activerecord
|
140
|
+
changelog_uri: https://github.com/procore-oss/blueprinter-activerecord/CHANGELOG.md
|
141
|
+
allowed_push_host: https://rubygems.org
|
142
|
+
rubygems_mfa_required: 'true'
|
143
|
+
post_install_message:
|
144
|
+
rdoc_options: []
|
145
|
+
require_paths:
|
146
|
+
- lib
|
147
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '2.7'
|
152
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
153
|
+
requirements:
|
154
|
+
- - ">="
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: '0'
|
157
|
+
requirements: []
|
158
|
+
rubygems_version: 3.4.19
|
159
|
+
signing_key:
|
160
|
+
specification_version: 4
|
161
|
+
summary: Extensions for using ActiveRecord with ActiveRecord
|
162
|
+
test_files: []
|