Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge and replace multiple preloads ourselves #14

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 6 additions & 31 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,11 @@
### 0.5.0 (2024-01-26)
## 1.0.2 (?)

* Adds an "auto" mode that automatically preloads every Blueprint-rendered query
* Adds a "dynamic" mode that allows a single block to decide which Blueprint-rendered queries get preloaded
* Adds two logging extensions for gathering preload stats before and after implementing the Preloader extension
- [BUGFIX] Fixes issue where ActiveRecord sometimes doesn't correctly merge Blueprinter-derived preloads with manually added preloads, resulting in dropped preloads and worse performance.

### 0.4.0 (2024-01-18)
## 1.0.1 (2024-02-09)

* Remove the Blueprinter reflection and extension stubs
* Require Blueprinter >= 1.0
- Fixed typo in gemspec

### 0.3.1 (2023-12-04)
## 1.0.0 (2024-02-09)

* Switches to a real Blueprinter Extension
* Autodetects Blueprinter and view on render
* Allows using `:includes` or `:eager_load` instead of `:preload`

### 0.1.3 (2023-10-16)

* [BUGFIX] Stop preloading when we hit a dynamic blueprint

### 0.1.2 (2023-10-03)

* [BUGFIX] Associations from included views were being missed

### 0.1.1 (2023-09-29)

* [BUGFIX] Open up to all 0.x blueprinter versions

### 0.1.0 (2023-09-25)

* [BUGFIX] Associations weren't being found if they used a custom name (e.g. `association :widget, blueprint: WidgetBlueprint, name: :wdgt`)

## 0.0.1 (2023-09-20)

* Initial release
- Initial release
3 changes: 2 additions & 1 deletion lib/blueprinter-activerecord/preloader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ def pre_render(object, blueprint, view, options)
if object.preload_blueprint_method || auto || auto_proc&.call(object, blueprint, view, options) == true
object.before_preload_blueprint = extract_preloads object
blueprint_preloads = self.class.preloads(blueprint, view, object.model)
unified_preloads = merge_values([*object.values[use], blueprint_preloads])
loader = object.preload_blueprint_method || use
object.public_send(loader, blueprint_preloads)
object.except(loader).public_send(loader, unified_preloads)
else
object
end
Expand Down
5 changes: 3 additions & 2 deletions lib/blueprinter-activerecord/query_methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ def preload_blueprint!(blueprint = nil, view = :default, use: :preload)

if blueprint and view
# preload right now
preloads = Preloader.preloads(blueprint, view, model)
public_send(use, preloads)
blueprint_preloads = Preloader.preloads(blueprint, view, model)
unified_preloads = Helpers.merge_values([*values[use], blueprint_preloads])
except(use).public_send(use, unified_preloads)
else
# preload during render
@values[:preload_blueprint_method] = use
Expand Down
2 changes: 1 addition & 1 deletion lib/blueprinter-activerecord/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module BlueprinterActiveRecord
VERSION = "1.0.1"
VERSION = "1.0.2"
end
25 changes: 25 additions & 0 deletions test/preloader_extension_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,17 @@ def test_blueprinter_preload_now
assert_equal [{:battery1=>{:fake_assoc=>{}, :refurb_plan=>{}}, :battery2=>{:fake_assoc=>{}, :refurb_plan=>{}}, :category=>{}, :project=>{:customer=>{}}}], q.values[:preload]
end

def test_blueprinter_preload_now_with_existing_preloads
q = Widget.
where("widgets.name <> ?", "Widget C").
order(:name).
preload({battery1: :refurb_plan}).
preload_blueprint(WidgetBlueprint, :no_power).
strict_loading

assert_equal [{:battery1=>{:refurb_plan=>{}}, :category=>{}, :project=>{:customer=>{}}}], q.values[:preload]
end

def test_auto_preload
ext = BlueprinterActiveRecord::Preloader.new(auto: true)
q = Widget.
Expand All @@ -121,6 +132,20 @@ def test_auto_preload
assert_equal [{:battery1=>{:fake_assoc=>{}, :refurb_plan=>{}}, :battery2=>{:fake_assoc=>{}, :refurb_plan=>{}}, :category=>{}, :project=>{:customer=>{}}}], q.values[:preload]
end

def test_auto_preload_with_existing_preloads
ext = BlueprinterActiveRecord::Preloader.new(auto: true)
q = Widget.
where("name <> ?", "Widget C").
order(:name).
preload({battery1: :refurb_plan}).
strict_loading
q = ext.pre_render(q, WidgetBlueprint, :no_power, {})

assert ext.auto
assert_equal :preload, ext.use
assert_equal [{:battery1=>{:refurb_plan=>{}}, :category=>{}, :project=>{:customer=>{}}}], q.values[:preload]
end

def test_auto_preload_with_block_true
ext = BlueprinterActiveRecord::Preloader.new { |object| true }
q = Widget.
Expand Down