diff --git a/lib/thermos.rb b/lib/thermos.rb index 315d381..867f659 100644 --- a/lib/thermos.rb +++ b/lib/thermos.rb @@ -8,14 +8,14 @@ require 'thermos/rebuild_cache_job' module Thermos - def self.keep_warm(key:, model:, id:, deps: [], lookup_key: nil, &block) - fill(key: key, model: model, deps: deps, lookup_key: lookup_key, &block) + def self.keep_warm(key:, model:, id:, deps: [], lookup_key: nil, filter: nil, &block) + fill(key: key, model: model, deps: deps, lookup_key: lookup_key, filter: filter, &block) drink(key: key, id: id) end - def self.fill(key:, model:, deps: [], lookup_key: nil, &block) + def self.fill(key:, model:, deps: [], lookup_key: nil, filter: nil, &block) BeverageStorage.instance.add_beverage( - Beverage.new(key: key, model: model, deps: deps, action: block, lookup_key: lookup_key) + Beverage.new(key: key, model: model, deps: deps, action: block, lookup_key: lookup_key, filter: filter) ) end diff --git a/lib/thermos/beverage.rb b/lib/thermos/beverage.rb index f56a8ae..da91f2f 100644 --- a/lib/thermos/beverage.rb +++ b/lib/thermos/beverage.rb @@ -2,12 +2,13 @@ module Thermos class Beverage - attr_reader :key, :model, :deps, :action, :lookup_key + attr_reader :key, :model, :deps, :action, :lookup_key, :filter - def initialize(key:, model:, deps:, action:, lookup_key: nil) + def initialize(key:, model:, deps:, action:, lookup_key: nil, filter: nil) @key = key @model = model @lookup_key = lookup_key || :id + @filter = filter || nil @deps = deps.map do |dep| Dependency.new(model: model, association: dep) end @@ -25,6 +26,10 @@ def lookup_keys_for_dep_model(dep_model) end.uniq end + def should_fill?(model) + @filter.class == Proc ? !!@filter.call(model) : true + end + private def set_observers diff --git a/lib/thermos/refill_job.rb b/lib/thermos/refill_job.rb index 6b66cf3..8eb515d 100644 --- a/lib/thermos/refill_job.rb +++ b/lib/thermos/refill_job.rb @@ -9,7 +9,7 @@ def perform(model) def refill_primary_caches(model) BeverageStorage.instance.beverages.each do |beverage| - if beverage.model == model.class + if beverage.model == model.class && beverage.should_fill?(model) Thermos::RebuildCacheJob.perform_later(beverage.key, model.send(beverage.lookup_key)) end end @@ -17,8 +17,10 @@ def refill_primary_caches(model) def refill_dependency_caches(model) BeverageStorage.instance.beverages.each do |beverage| - beverage.lookup_keys_for_dep_model(model).each do |lookup_key| - Thermos::RebuildCacheJob.perform_later(beverage.key, lookup_key) + if beverage.should_fill?(model) + beverage.lookup_keys_for_dep_model(model).each do |lookup_key| + Thermos::RebuildCacheJob.perform_later(beverage.key, lookup_key) + end end end end diff --git a/lib/thermos/version.rb b/lib/thermos/version.rb index db671d0..5e25762 100644 --- a/lib/thermos/version.rb +++ b/lib/thermos/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Thermos - VERSION = '0.3.0' + VERSION = '0.4.0' end diff --git a/test/dummy/db/schema.rb b/test/dummy/db/schema.rb index 3a75ca5..5fd34bf 100644 --- a/test/dummy/db/schema.rb +++ b/test/dummy/db/schema.rb @@ -2,11 +2,11 @@ # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. # -# Note that this schema.rb definition is the authoritative source for your -# database schema. If you need to create the application database on another -# system, you should be using db:schema:load, not running all the migrations -# from scratch. The latter is a flawed and unsustainable approach (the more migrations -# you'll amass, the slower it'll run and the greater likelihood for issues). +# This file is the source Rails uses to define your schema when running `rails +# db:schema:load`. When creating a new database, `rails db:schema:load` tends to +# be faster and is potentially less error prone than running all of your +# migrations from scratch. Old migrations may fail to apply correctly if those +# migrations use external dependencies or application code. # # It's strongly recommended that you check this file into your version control system. diff --git a/test/thermos_test.rb b/test/thermos_test.rb index 5a00df0..0b25772 100644 --- a/test/thermos_test.rb +++ b/test/thermos_test.rb @@ -126,6 +126,23 @@ def teardown assert_equal 1, Thermos.drink(key: "key", id: "foo") assert_raises(MockExpectationError) { mock.verify } end + + test "allows filtering for which records should be rebuilt" do + mock = Minitest::Mock.new + category = categories(:baseball) + filter = ->(model) { model.name.match("ball") } + Thermos.fill(key: "key", model: Category, lookup_key: "name", filter: filter) do |name| + mock.call(name) + end + + mock.expect(:call, 1, ["basketball"]) + category.update!(name: "basketball") + mock.verify + + mock.expect(:call, 1, ["hockey"]) + category.update!(name: "hockey") + assert_raises(MockExpectationError) { mock.verify } + end # has_many model changes test "rebuilds the cache on has_many model change" do