[deploy] Copy ActiveRecord methods from fastly-rails (#7145)
* Add comment referencing Fastly gem * Create purgable concern and include it * Typo: deprecate --> deprecated * Include Purgable on the Tag model * Rename Purgable to Purgeable * Reorganize fastly and service methods in Purgeable * Add and fix specs * Add development env guards
This commit is contained in:
parent
e4de9c2742
commit
7dfffac3db
6 changed files with 192 additions and 1 deletions
|
|
@ -7,6 +7,17 @@ module CacheBuster
|
|||
].freeze
|
||||
|
||||
def self.bust(path)
|
||||
# TODO: (Alex Smith) - It would be "nice to have" the ability to use the
|
||||
# Fastly gem here instead of custom API calls. We'd want to keep thread
|
||||
# safety in mind. We'll also want to consider making this modular for those
|
||||
# who don't want to use Fastly at all.
|
||||
#
|
||||
# Instead of HTTP calls, we could do:
|
||||
# fastly = Fastly.new(api_key: ApplicationConfig["FASTLY_API_KEY"])
|
||||
# service = Fastly::Service.new({ id: ApplicationConfig["FASTLY_SERVICE_ID"] }, fastly)
|
||||
# fastly.purge(path)
|
||||
#
|
||||
# https://github.com/fastly/fastly-ruby#efficient-purging
|
||||
return unless Rails.env.production?
|
||||
|
||||
HTTParty.post("https://api.fastly.com/purge/https://#{ApplicationConfig['APP_DOMAIN']}#{path}",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
class ApplicationRecord < ActiveRecord::Base
|
||||
self.abstract_class = true
|
||||
|
||||
include Purgeable
|
||||
|
||||
QUERY_ESTIMATED_COUNT = <<~SQL.squish.freeze
|
||||
SELECT (
|
||||
(reltuples / GREATEST(relpages, 1)) *
|
||||
|
|
|
|||
74
app/models/concerns/purgeable.rb
Normal file
74
app/models/concerns/purgeable.rb
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# Copied from the deprecated fastly-rails gem
|
||||
# https://github.com/fastly/fastly-rails/blob/master/lib/fastly-rails/active_record/surrogate_key.rb
|
||||
#
|
||||
# This concern handles purge and purge_all calls to purge the edge cache (Fastly)
|
||||
module Purgeable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
module ClassMethods
|
||||
def purge_all
|
||||
return if Rails.env.development?
|
||||
|
||||
service.purge_by_key(table_key)
|
||||
end
|
||||
|
||||
def soft_purge_all
|
||||
return if Rails.env.development?
|
||||
|
||||
service.purge_by_key(table_key, true)
|
||||
end
|
||||
|
||||
def table_key
|
||||
table_name
|
||||
end
|
||||
|
||||
def fastly
|
||||
return if Rails.env.development?
|
||||
|
||||
Fastly.new(api_key: ApplicationConfig["FASTLY_API_KEY"])
|
||||
end
|
||||
|
||||
def service
|
||||
return if Rails.env.development?
|
||||
|
||||
Fastly::Service.new({ id: ApplicationConfig["FASTLY_SERVICE_ID"] }, fastly)
|
||||
end
|
||||
end
|
||||
|
||||
# Instance methods
|
||||
def record_key
|
||||
"#{table_key}/#{id}"
|
||||
end
|
||||
|
||||
def table_key
|
||||
self.class.table_key
|
||||
end
|
||||
|
||||
def purge
|
||||
return if Rails.env.development?
|
||||
|
||||
service.purge_by_key(record_key)
|
||||
end
|
||||
|
||||
def soft_purge
|
||||
return if Rails.env.development?
|
||||
|
||||
service.purge_by_key(record_key, true)
|
||||
end
|
||||
|
||||
def purge_all
|
||||
self.class.purge_all
|
||||
end
|
||||
|
||||
def soft_purge_all
|
||||
self.class.soft_purge_all
|
||||
end
|
||||
|
||||
def fastly
|
||||
self.class.fastly
|
||||
end
|
||||
|
||||
def service
|
||||
self.class.service
|
||||
end
|
||||
end
|
||||
|
|
@ -39,6 +39,9 @@ class Tag < ActsAsTaggableOn::Tag
|
|||
SEARCH_SERIALIZER = Search::TagSerializer
|
||||
SEARCH_CLASS = Search::Tag
|
||||
|
||||
# This model doesn't inherit from ApplicationRecord so this has to be included
|
||||
include Purgeable
|
||||
|
||||
# possible social previews templates for articles with a particular tag
|
||||
def self.social_preview_templates
|
||||
Rails.root.join("app/views/social_previews/articles").children.map { |ch| File.basename(ch, ".html.erb") }
|
||||
|
|
|
|||
101
spec/models/concerns/purgeable_spec.rb
Normal file
101
spec/models/concerns/purgeable_spec.rb
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
require "rails_helper"
|
||||
|
||||
class PurgeableModel
|
||||
include Purgeable
|
||||
|
||||
def self.table_name
|
||||
"purgeables"
|
||||
end
|
||||
|
||||
def id
|
||||
1
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.describe Purgeable do
|
||||
let(:model_class) { PurgeableModel }
|
||||
let(:purgeable_model) { model_class.new }
|
||||
let(:fastly_service) { instance_double(Fastly::Service) }
|
||||
|
||||
before do
|
||||
allow(Fastly::Service).to receive(:new).and_return(fastly_service)
|
||||
end
|
||||
|
||||
describe "class methods" do
|
||||
it "calls .purge_by_key with table_key in purge_all" do
|
||||
allow(fastly_service).to receive(:purge_by_key)
|
||||
model_class.purge_all
|
||||
expect(fastly_service).to have_received(:purge_by_key).with(model_class.table_key)
|
||||
end
|
||||
|
||||
it "calls .purge_by_key with table_key and true in soft_purge_all" do
|
||||
allow(fastly_service).to receive(:purge_by_key)
|
||||
model_class.soft_purge_all
|
||||
expect(fastly_service).to have_received(:purge_by_key).with(model_class.table_key, true)
|
||||
end
|
||||
|
||||
it "returns table_name with table_key" do
|
||||
expect(model_class.table_key).to eq(model_class.table_name)
|
||||
end
|
||||
|
||||
it "returns a Fastly object" do
|
||||
fastly = instance_double(Fastly)
|
||||
allow(Fastly).to receive(:new).and_return(fastly)
|
||||
model_class.fastly
|
||||
expect(Fastly).to have_received(:new)
|
||||
end
|
||||
|
||||
it "returns a Fastly::Service object" do
|
||||
model_class.service
|
||||
expect(Fastly::Service).to have_received(:new)
|
||||
end
|
||||
end
|
||||
|
||||
describe "instance methods" do
|
||||
it "returns a record key" do
|
||||
expect(purgeable_model.record_key).to eq("purgeables/1")
|
||||
end
|
||||
|
||||
it "returns a table_key" do
|
||||
allow(model_class).to receive(:table_key).and_return(model_class.table_name)
|
||||
expect(purgeable_model.table_key).to eq(model_class.table_name)
|
||||
expect(model_class).to have_received(:table_key)
|
||||
end
|
||||
|
||||
it "calls .purge_by_key with record_key in purge" do
|
||||
allow(fastly_service).to receive(:purge_by_key)
|
||||
purgeable_model.purge
|
||||
expect(fastly_service).to have_received(:purge_by_key).with(purgeable_model.record_key)
|
||||
end
|
||||
|
||||
it "calls .purge_by_key with record_key and true in soft_purge" do
|
||||
allow(fastly_service).to receive(:purge_by_key)
|
||||
purgeable_model.soft_purge
|
||||
expect(fastly_service).to have_received(:purge_by_key).with(purgeable_model.record_key, true)
|
||||
end
|
||||
|
||||
it "calls purge_all class method" do
|
||||
allow(model_class).to receive(:purge_all)
|
||||
purgeable_model.purge_all
|
||||
expect(model_class).to have_received(:purge_all)
|
||||
end
|
||||
|
||||
it "calls soft_purge_all class method" do
|
||||
allow(model_class).to receive(:soft_purge_all)
|
||||
purgeable_model.soft_purge_all
|
||||
expect(model_class).to have_received(:soft_purge_all)
|
||||
end
|
||||
|
||||
it "calls the fastly class method" do
|
||||
allow(model_class).to receive(:fastly)
|
||||
purgeable_model.fastly
|
||||
expect(model_class).to have_received(:fastly)
|
||||
end
|
||||
|
||||
it "calls the service class method" do
|
||||
allow(model_class).to receive(:service)
|
||||
purgeable_model.service
|
||||
expect(model_class).to have_received(:service)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -113,7 +113,7 @@ RSpec.configure do |config|
|
|||
stub_request(:any, /res.cloudinary.com/).to_rack("dsdsdsds")
|
||||
|
||||
stub_request(:post, /api.fastly.com/).
|
||||
to_return(status: 200, body: "", headers: {})
|
||||
to_return(status: 200, body: "".to_json, headers: {})
|
||||
|
||||
stub_request(:post, /api.bufferapp.com/).
|
||||
to_return(status: 200, body: { fake_text: "so fake" }.to_json, headers: {})
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue